When are structs the answer?

前端 未结 12 799
广开言路
广开言路 2020-12-12 18:24

I\'m doing a raytracer hobby project, and originally I was using structs for my Vector and Ray objects, and I thought a raytracer was the perfect situation to use them: you

相关标签:
12条回答
  • 2020-12-12 18:52

    If the structs are small, and not too many exist at once, it SHOULD be placing them on the stack (as long as its a local variable and not a member of a class) and not on the heap, this means the GC doesn't need to be invoked and memory allocation/deallocation should be almost instantaneous.

    When passing a struct as a parameter to function, the struct is copied, which not only means more allocations/deallocations (from the stack, which is almost instantaneous, but still has overhead), but the overhead in just transferring data between the 2 copies. If you pass via reference, this is a non issue as you are just telling it where to read the data from, rather than copying it.

    I'm not 100% sure on this, but i suspect that returning arrays via an 'out' parameter may also give you a speed boost, as memory on the stack is reserved for it and doesn't need to be copied as the stack is "unwound" at the end of function calls.

    0 讨论(0)
  • 2020-12-12 18:58

    I think the key lies in these two statements from your post:

    you create millions of them

    and

    I do pass them to methods when needed of course

    Now unless your struct is less than or equal to 4 bytes in size (or 8 bytes if you are on a 64-bit system) you are copying much more on each method call then if you simply passed an object reference.

    0 讨论(0)
  • 2020-12-12 18:59

    My own ray tracer also uses struct Vectors (though not Rays) and changing Vector to class does not appear to have any impact on the performance. I'm currently using three doubles for the vector so it might be bigger than it ought to be. One thing to note though, and this might be obvious but it wasn't for me, and that is to run the program outside of visual studio. Even if you set it to optimized release build you can get a massive speed boost if you start the exe outside of VS. Any benchmarking you do should take this into consideration.

    0 讨论(0)
  • 2020-12-12 19:00

    In the recommendations for when to use a struct it says that it should not be larger than 16 bytes. Your Vector is 12 bytes, which is close to the limit. The Ray has two Vectors, putting it at 24 bytes, which is clearly over the recommended limit.

    When a struct gets larger than 16 bytes it can no longer be copied efficiently with a single set of instructions, instead a loop is used. So, by passing this "magic" limit, you are actually doing a lot more work when you pass a struct than when you pass a reference to an object. This is why the code is faster with classes eventhough there is more overhead when allocating the objects.

    The Vector could still be a struct, but the Ray is simply too large to work well as a struct.

    0 讨论(0)
  • 2020-12-12 19:02

    Anything written regarding boxing/unboxing prior to .NET generics can be taken with something of a grain of salt. Generic collection types have removed the need for boxing and unboxing of value types, which makes using structs in these situations more valuable.

    As for your specific slowdown - we'd probably need to see some code.

    0 讨论(0)
  • 2020-12-12 19:04

    While the functionality is similar, structures are usually more efficient than classes. You should define a structure, rather than a class, if the type will perform better as a value type than a reference type.

    Specifically, structure types should meet all of these criteria:

    • Logically represents a single value
    • Has an instance size less than 16 bytes
    • Will not be changed after creation
    • Will not be cast to a reference type
    0 讨论(0)
提交回复
热议问题