Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Primitive types or object types what to prefer

Primitive types or object types what to prefer

Scheduled Pinned Locked Moved C#
csharpperformancequestion
13 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    ComCoderCsharp
    wrote on last edited by
    #1

    Hi everybody I'm doing a project were I need to do some advanced calculations on complex numbers. So I'm wondering if I should use a struct/class to represent the Complex data or should I use two arrays of primitive types to handle the real and complex part seperately. Is it more memory effecient to use primitive types than self-defined types?. I have read somewhere that primitive types in C# are objects themself, so I was wondering, if I define e.g a ComplexNumber class, would it be the same as using e.g float which is inheritet from System.Object?... Thanks in advance T

    S L 3 Replies Last reply
    0
    • C ComCoderCsharp

      Hi everybody I'm doing a project were I need to do some advanced calculations on complex numbers. So I'm wondering if I should use a struct/class to represent the Complex data or should I use two arrays of primitive types to handle the real and complex part seperately. Is it more memory effecient to use primitive types than self-defined types?. I have read somewhere that primitive types in C# are objects themself, so I was wondering, if I define e.g a ComplexNumber class, would it be the same as using e.g float which is inheritet from System.Object?... Thanks in advance T

      S Offline
      S Offline
      Stefan Troschuetz
      wrote on last edited by
      #2

      Take a look at the following MSDN resource to learn something about the Class and struct differences[^]. To come to your concrete problem: I would define a ComplexNumber structure because the primitive types like int or double are structures too and this way the general handling of a ComplexNumber would be similar to dealing with another primitive type.


      "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook

      www.troschuetz.de

      1 Reply Last reply
      0
      • C ComCoderCsharp

        Hi everybody I'm doing a project were I need to do some advanced calculations on complex numbers. So I'm wondering if I should use a struct/class to represent the Complex data or should I use two arrays of primitive types to handle the real and complex part seperately. Is it more memory effecient to use primitive types than self-defined types?. I have read somewhere that primitive types in C# are objects themself, so I was wondering, if I define e.g a ComplexNumber class, would it be the same as using e.g float which is inheritet from System.Object?... Thanks in advance T

        L Offline
        L Offline
        Luc Pattyn
        wrote on last edited by
        #3

        Hi, A ComplexNumber class would use 16 bytes to store two 4B numbers (real+imag parts) plus 8B of administrative stuff. So it effectively doubles the memory requirements, which is only really significant if you are going to need more than 1M of those numbers. I am not sure whether a struct has the same memory overhead or not. But this is simple to find out: just create a small program than creates 1M complex numbers (as 2 floats, as a struct, as a class) and in each case compare its memory footprint before and after creation (make sure the objects are still alive when you measure (e.g. by including code to sum them up, then print the sum). The calculation cost will be different too. With a class, the natural way would be to write methods that return a new object (say c=a+b), which involves calling the method, doing very simple arithmetic, creating a new object, and returning it. (And this is what you would have to do if you want to overload the + - * operators) A cheaper approach would be to provide methods that do not return results, but modify their parameters, something like: static void AddTo(ComplexNumber a, ComplexNumber b); // performs a=a+b of course, if ComplexNumber is a struct, you would use ref everywhere (obviously for in/out values, but I recommend it for input-only parameters too). The cheapest, but hardest way, would be to forget about a complex class/struct and write everything in real numbers, with explicit add/multiply code all over the place. Completely unstructured, very error prone and the fastest (at run-time that is). If your application needs a lot of complex functions (hence a lot of code), I would go for a class with overloaded operators, so you can really write c=a+b with abc all complex. If the number of formulas is limited, I would suggest you start with a ComplexNumber struct and use explicit method calls for each operation; but avoid creating objects all the time, and certainly do not rely on methods that return a struct: instead have them modify an already existing struct. If in the end you are still convinced it needs to be faster and/or smaller, you could then revisit the initial choice. But dont start it in the hard way from day 1. But I do not expect you to really need this, unless you are chasing the next Mersenne prime or so... Hope this is helpful. :)

        Luc Pattyn

        C S 2 Replies Last reply
        0
        • L Luc Pattyn

          Hi, A ComplexNumber class would use 16 bytes to store two 4B numbers (real+imag parts) plus 8B of administrative stuff. So it effectively doubles the memory requirements, which is only really significant if you are going to need more than 1M of those numbers. I am not sure whether a struct has the same memory overhead or not. But this is simple to find out: just create a small program than creates 1M complex numbers (as 2 floats, as a struct, as a class) and in each case compare its memory footprint before and after creation (make sure the objects are still alive when you measure (e.g. by including code to sum them up, then print the sum). The calculation cost will be different too. With a class, the natural way would be to write methods that return a new object (say c=a+b), which involves calling the method, doing very simple arithmetic, creating a new object, and returning it. (And this is what you would have to do if you want to overload the + - * operators) A cheaper approach would be to provide methods that do not return results, but modify their parameters, something like: static void AddTo(ComplexNumber a, ComplexNumber b); // performs a=a+b of course, if ComplexNumber is a struct, you would use ref everywhere (obviously for in/out values, but I recommend it for input-only parameters too). The cheapest, but hardest way, would be to forget about a complex class/struct and write everything in real numbers, with explicit add/multiply code all over the place. Completely unstructured, very error prone and the fastest (at run-time that is). If your application needs a lot of complex functions (hence a lot of code), I would go for a class with overloaded operators, so you can really write c=a+b with abc all complex. If the number of formulas is limited, I would suggest you start with a ComplexNumber struct and use explicit method calls for each operation; but avoid creating objects all the time, and certainly do not rely on methods that return a struct: instead have them modify an already existing struct. If in the end you are still convinced it needs to be faster and/or smaller, you could then revisit the initial choice. But dont start it in the hard way from day 1. But I do not expect you to really need this, unless you are chasing the next Mersenne prime or so... Hope this is helpful. :)

          Luc Pattyn

          C Offline
          C Offline
          ComCoderCsharp
          wrote on last edited by
          #4

          Thanks for your answers guys It really cleared some things up for me. The thing is that I'm doing some complex numbers math on sound data, so memory space is important. I'm using about 2^16=131072 samples data and if I do the Fourier transformation this will double up, because of the complex representation. This will end up something like 2^16*2*16=4194304 bytes ~4.2M which is a lot. So I'm thinking maybe I should do it the hard way... If you you have something to add I'm open to suggestions...:) Best wishes T

          K 1 Reply Last reply
          0
          • C ComCoderCsharp

            Thanks for your answers guys It really cleared some things up for me. The thing is that I'm doing some complex numbers math on sound data, so memory space is important. I'm using about 2^16=131072 samples data and if I do the Fourier transformation this will double up, because of the complex representation. This will end up something like 2^16*2*16=4194304 bytes ~4.2M which is a lot. So I'm thinking maybe I should do it the hard way... If you you have something to add I'm open to suggestions...:) Best wishes T

            K Offline
            K Offline
            Kevin McFarlane
            wrote on last edited by
            #5

            NMath's complex number types - http://www.centerspace.net/doc/NMath/Core/user/complex.html#77053[^]

            Kevin

            1 Reply Last reply
            0
            • L Luc Pattyn

              Hi, A ComplexNumber class would use 16 bytes to store two 4B numbers (real+imag parts) plus 8B of administrative stuff. So it effectively doubles the memory requirements, which is only really significant if you are going to need more than 1M of those numbers. I am not sure whether a struct has the same memory overhead or not. But this is simple to find out: just create a small program than creates 1M complex numbers (as 2 floats, as a struct, as a class) and in each case compare its memory footprint before and after creation (make sure the objects are still alive when you measure (e.g. by including code to sum them up, then print the sum). The calculation cost will be different too. With a class, the natural way would be to write methods that return a new object (say c=a+b), which involves calling the method, doing very simple arithmetic, creating a new object, and returning it. (And this is what you would have to do if you want to overload the + - * operators) A cheaper approach would be to provide methods that do not return results, but modify their parameters, something like: static void AddTo(ComplexNumber a, ComplexNumber b); // performs a=a+b of course, if ComplexNumber is a struct, you would use ref everywhere (obviously for in/out values, but I recommend it for input-only parameters too). The cheapest, but hardest way, would be to forget about a complex class/struct and write everything in real numbers, with explicit add/multiply code all over the place. Completely unstructured, very error prone and the fastest (at run-time that is). If your application needs a lot of complex functions (hence a lot of code), I would go for a class with overloaded operators, so you can really write c=a+b with abc all complex. If the number of formulas is limited, I would suggest you start with a ComplexNumber struct and use explicit method calls for each operation; but avoid creating objects all the time, and certainly do not rely on methods that return a struct: instead have them modify an already existing struct. If in the end you are still convinced it needs to be faster and/or smaller, you could then revisit the initial choice. But dont start it in the hard way from day 1. But I do not expect you to really need this, unless you are chasing the next Mersenne prime or so... Hope this is helpful. :)

              Luc Pattyn

              S Offline
              S Offline
              Scott Dorman
              wrote on last edited by
              #6

              I'm not sure I completely follow your reasoning here. The native data types like int, byte, datetime, etc. are all structs. A struct automatically inherits from System.ValueType. If I were implementing a ComplexNumber object, I would want it to have the same behavior as the native data types. A struct also allows you to overload operators, so there would be no problems implementing code like c = a + b. Also, if the code is going to be creating a lot of these types of objects, which it sounds like it would be, you don't want the extra overhead of creating a class each time and having to store it on the heap. I would take a look at how one of the native data types are defined using either reflector or Rotor and pattern the object from that.

              ----------------------------- In just two days, tomorrow will be yesterday.

              L 1 Reply Last reply
              0
              • S Scott Dorman

                I'm not sure I completely follow your reasoning here. The native data types like int, byte, datetime, etc. are all structs. A struct automatically inherits from System.ValueType. If I were implementing a ComplexNumber object, I would want it to have the same behavior as the native data types. A struct also allows you to overload operators, so there would be no problems implementing code like c = a + b. Also, if the code is going to be creating a lot of these types of objects, which it sounds like it would be, you don't want the extra overhead of creating a class each time and having to store it on the heap. I would take a look at how one of the native data types are defined using either reflector or Rotor and pattern the object from that.

                ----------------------------- In just two days, tomorrow will be yesterday.

                L Offline
                L Offline
                Luc Pattyn
                wrote on last edited by
                #7

                Sure, for ease of use I would implement ComplexNumber as a class or struct, with operators overloaded. For performance reasons I would rather not use classes (too many objects), and not return structs (too many data moves; for 8B of data it is debatable, for large structs I certainly dont want them returned), hence ref struct, hence no operator overloads. And of course for max performance, no ComplexNumbers at all. :)

                Luc Pattyn

                S 1 Reply Last reply
                0
                • L Luc Pattyn

                  Sure, for ease of use I would implement ComplexNumber as a class or struct, with operators overloaded. For performance reasons I would rather not use classes (too many objects), and not return structs (too many data moves; for 8B of data it is debatable, for large structs I certainly dont want them returned), hence ref struct, hence no operator overloads. And of course for max performance, no ComplexNumbers at all. :)

                  Luc Pattyn

                  S Offline
                  S Offline
                  Scott Dorman
                  wrote on last edited by
                  #8

                  Luc Pattyn wrote:

                  Sure, for ease of use I would implement ComplexNumber as a class or struct, with operators overloaded.

                  I guess your original post didn't seem clear to me.

                  Luc Pattyn wrote:

                  For performance reasons I would rather not use classes (too many objects), and not return structs (too many data moves; for 8B of data it is debatable, for large structs I certainly dont want them returned), hence ref struct, hence no operator overloads.

                  From the MSDN[^] docs: A struct can be considered a lightweight class, ideal for creating data types that store small amounts of data, and does not represent a type that might later be extended via inheritance. I don't see how the performance of a struct is going to be detrimental if the "rules" are followed. Again, all of the native data types are implemeneted using structs and there aren't any perforamnce issues with them.

                  ----------------------------- In just two days, tomorrow will be yesterday.

                  C 1 Reply Last reply
                  0
                  • S Scott Dorman

                    Luc Pattyn wrote:

                    Sure, for ease of use I would implement ComplexNumber as a class or struct, with operators overloaded.

                    I guess your original post didn't seem clear to me.

                    Luc Pattyn wrote:

                    For performance reasons I would rather not use classes (too many objects), and not return structs (too many data moves; for 8B of data it is debatable, for large structs I certainly dont want them returned), hence ref struct, hence no operator overloads.

                    From the MSDN[^] docs: A struct can be considered a lightweight class, ideal for creating data types that store small amounts of data, and does not represent a type that might later be extended via inheritance. I don't see how the performance of a struct is going to be detrimental if the "rules" are followed. Again, all of the native data types are implemeneted using structs and there aren't any perforamnce issues with them.

                    ----------------------------- In just two days, tomorrow will be yesterday.

                    C Offline
                    C Offline
                    ComCoderCsharp
                    wrote on last edited by
                    #9

                    Hi again I have read a bit up on which types to prefer and it seems to me that defining a struct and using it as a primitive type, would be the same as just using primitive types which are structs themself. This means that if I want to represent some complex data (Re,Im). I could do it using two e.g float arrays representing the real part and the imag part, but it would be the same, if I used a struct called Complex(float,float). In other words: float[] = realdata; float[] = Imagdata; would be the same as: Complex[,] = new Complex(realdata,Imagdata); Right? :^) All the best T

                    S 1 Reply Last reply
                    0
                    • C ComCoderCsharp

                      Hi again I have read a bit up on which types to prefer and it seems to me that defining a struct and using it as a primitive type, would be the same as just using primitive types which are structs themself. This means that if I want to represent some complex data (Re,Im). I could do it using two e.g float arrays representing the real part and the imag part, but it would be the same, if I used a struct called Complex(float,float). In other words: float[] = realdata; float[] = Imagdata; would be the same as: Complex[,] = new Complex(realdata,Imagdata); Right? :^) All the best T

                      S Offline
                      S Offline
                      Scott Dorman
                      wrote on last edited by
                      #10

                      You are essentially correct. The benefit to defining your own struct is that you can then ecapsulate the two parts of a complex number and define the arithmetic rules (+, -, etc.) which allows you to treat the complex number as if it were a native data type. I'm not sure why you would want to use arrays in the way you are showing. Defining a ComplexNumber struct would allow you to do something like this:

                      ComplexNumber c = new ComplexNumber(real, imaginary);
                      Console.WriteLine("Complex Number Real: {0}, Imaginary: {1}", c.Real, c.Imaginary);

                      ComplexNumber d = new ComplexNumber(real2, imaginary2);
                      ComplexNumber e = c + d;

                      Console.WriteLine("Complex Number Real: {0}, Imaginary: {1}", e.Real, e.Imaginary);

                      The benefit here is that the ComplexNumber knows how to add two complex numbers together and the calling code doesn't need that complexity. If you wanted to use this in an array, it would be something like this:

                      Complex[] complexArray = new Complex[3];

                      complexArray[0] = new ComplexNumber(real, imaginary);
                      complexArray[1] = new ComplexNumber(real2, imaginary2);
                      complexArray[2] = new ComplexNumber(real3, imaginary3);

                      ----------------------------- In just two days, tomorrow will be yesterday.

                      C 1 Reply Last reply
                      0
                      • S Scott Dorman

                        You are essentially correct. The benefit to defining your own struct is that you can then ecapsulate the two parts of a complex number and define the arithmetic rules (+, -, etc.) which allows you to treat the complex number as if it were a native data type. I'm not sure why you would want to use arrays in the way you are showing. Defining a ComplexNumber struct would allow you to do something like this:

                        ComplexNumber c = new ComplexNumber(real, imaginary);
                        Console.WriteLine("Complex Number Real: {0}, Imaginary: {1}", c.Real, c.Imaginary);

                        ComplexNumber d = new ComplexNumber(real2, imaginary2);
                        ComplexNumber e = c + d;

                        Console.WriteLine("Complex Number Real: {0}, Imaginary: {1}", e.Real, e.Imaginary);

                        The benefit here is that the ComplexNumber knows how to add two complex numbers together and the calling code doesn't need that complexity. If you wanted to use this in an array, it would be something like this:

                        Complex[] complexArray = new Complex[3];

                        complexArray[0] = new ComplexNumber(real, imaginary);
                        complexArray[1] = new ComplexNumber(real2, imaginary2);
                        complexArray[2] = new ComplexNumber(real3, imaginary3);

                        ----------------------------- In just two days, tomorrow will be yesterday.

                        C Offline
                        C Offline
                        ComCoderCsharp
                        wrote on last edited by
                        #11

                        Hi again Thanks for the answer. I agree on what you are saying, this is how I have done it through out my project. I just wanted to know if there possible was a better way. My concern was that when I use a Complex array of e.g 100000 values and every time using the "new" inside a loop and thereby assigning a new memory location every time, would lead to a unnessecery usage of memory. So initially I was wondering if this could be avoided using primitive types. But this does not seeme to be the case - I think:) All the best T

                        S 1 Reply Last reply
                        0
                        • C ComCoderCsharp

                          Hi again Thanks for the answer. I agree on what you are saying, this is how I have done it through out my project. I just wanted to know if there possible was a better way. My concern was that when I use a Complex array of e.g 100000 values and every time using the "new" inside a loop and thereby assigning a new memory location every time, would lead to a unnessecery usage of memory. So initially I was wondering if this could be avoided using primitive types. But this does not seeme to be the case - I think:) All the best T

                          S Offline
                          S Offline
                          Scott Dorman
                          wrote on last edited by
                          #12

                          No matter what, you will be allocating memory in every iteration of the loop. The only difference is that you would allocating memory to hold a ComplexNumber struct as opposed to individual native data types. Because structs are a value type, they handle memory a bit differently than classes. The biggest difference is that structs are stored on the stack and are collected shortly after that stack frame goes out of scope. The other big difference is that structs actually store their values rather than references to them.

                          ----------------------------- In just two days, tomorrow will be yesterday.

                          1 Reply Last reply
                          0
                          • C ComCoderCsharp

                            Hi everybody I'm doing a project were I need to do some advanced calculations on complex numbers. So I'm wondering if I should use a struct/class to represent the Complex data or should I use two arrays of primitive types to handle the real and complex part seperately. Is it more memory effecient to use primitive types than self-defined types?. I have read somewhere that primitive types in C# are objects themself, so I was wondering, if I define e.g a ComplexNumber class, would it be the same as using e.g float which is inheritet from System.Object?... Thanks in advance T

                            L Offline
                            L Offline
                            Luc Pattyn
                            wrote on last edited by
                            #13

                            Hi, Having read lots of considerations, some experiments seemed overdue. So I developed a little test to actually see memory footprint and execution times for the different complex number approaches. My test first allocates and initializes 5 million complex numbers stored - as two float arrays - as one array of class ComplexClass instances - as one array of struct ComplexStruct as expected the numbers were 40MB, 100MB and 40MB respectively, proving the class instance takes 8B of overhead plus 4B for the pointer (32bit Windows), the struct has no memory overhead. Then I continued to measure the time required to square these numbers; I did 5M multiplies, involving only the first 16K of the numbers in each array (in order to avoid cache misses), and measured elapsed time. A release build with Visual 7.1 (.NET 1.1) and Visual 8.0 (.NET 2.0) respectively, running on a Pentium M at 1.7GHz, performing multiple passes, yielded the following numbers:

                            	.NET 1.1		.NET 2.0
                            

                            floats 4110 msec 3970 msec
                            class 4480 msec 4330 msec
                            structs 4150 msec 4080 msec
                            ref structs 4060 msec 3970 msec

                            The good news here is performance is very much the same in all cases (slightly over 1M mul/sec); the class is some 10% slower, and the ref struct is the best; also NET2.0 is marginally faster than NET1.1 here. Conclusions: - struct is cheaper than class in RAM and cycles (as expected) - ref struct is faster than struct (as expected) but only marginally so - the hard way does not bring anything with respect to ref structs (the positive surprise). So whenever I would need complex numbers, I would go for structs. The compiler seems good enough to make the hard way pointless. Cheers

                            Luc Pattyn

                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups