Search Unity

Performance question (in using integers)

Discussion in 'Scripting' started by skinner92, Feb 13, 2016.

  1. skinner92

    skinner92

    Joined:
    Feb 23, 2014
    Posts:
    112
    Hello all.

    Let's suppose we have a game in which we need to store the number of enemies in the map. We know this number is somewhere between 0 and 200.

    My question is: should we use a "byte" type for storing the number of enemies, or is it better to use an "int" here? Obviously, the "byte" type weighs 4 times less than the "int" type (8 bits vs 32 bits). Or maybe using "ushort"?

    So from a performance point of view, we should use "byte" whenever possible instead of "ints", right? Using an "int" for storing positive and short values is like killing a flea with a sledgehammer.

    So my question is why most developers ignore this fact and keep using "int" instead of "byte" or even "ushort". Is it for convenience or something?

    Thanks
     
  2. grizzly

    grizzly

    Joined:
    Dec 5, 2012
    Posts:
    357
    Ints are generally faster since CPUs are more efficient working with 32bit values. Bytes would primarily be used to reduce memory. Working with large files, streaming data etc.
     
  3. skinner92

    skinner92

    Joined:
    Feb 23, 2014
    Posts:
    112
    So when developing for a Mobile Device, is it better to have an array of 500 int-type or an array of 500 byte-type? (or 500 ushort-type?). Why do CPUs work more efficiently with 32 bit values? Do you have any benchmark or something? Thanks.
     
    Last edited: Feb 13, 2016
  4. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    974
    CPU registers are designed to work with 32 bit/64 bit values, so there is no gain by using bytes once you are in the CPU.

    Storing on the stack/heap is another matter.. You could technically work with bytes to save a bit of space and possibly a bit of time when copying values around but, honestly, these kinds of optimizations will not save you much processing time. You might be interested in some of the later posts in this thread http://forum.unity3d.com/threads/opinions-about-tokenizing.362531/

    The main reason I would just work with int instead of byte is to avoid needing to deal with casts whenever I need to do a standard number operation. There are plenty of times I want to use a math library or some other API, and the typical c# approach to dealing with numbers is to use ints so a lot of frameworks support this type exclusively.

    Another argument is extensibility. You may be certain the number will be between 0 and 200 today, but you're not leaving a lot of space for tomorrow. What happens when someone wants just another 57 enemies? You or they will have a bunch of refactoring to do just for a few milliseconds of performance tuning.

    When you're dealing with devices with small amounts of RAM, sometimes these optimizations make sense. If you are on the threshold of memory use where the device needs to resort to paging, your performance gain by using smaller memory structures might be much more significant. However, I would wait until the last minute, when you have real performance data on your targeted device, to make these kinds of optimizations.
     
    Last edited: Feb 13, 2016
    heu3becteh, skinner92 and lordofduct like this.
  5. skinner92

    skinner92

    Joined:
    Feb 23, 2014
    Posts:
    112
    Thanks eisenpony, exactly what I was looking for :)
     
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    byte's won't save you CPU speed (and sometimes increase it due to conversion, as eisenpony was talking about).

    byte's are useful for compacting memory. An array of bytes will take up less space than an array of ints. But at 500 ints, you're talking an array that is merely 1.96 Kbytes in size. So what...

    You'll notice the .Net framework uses byte arrays in few places.

    Streams - streams, because a stream is a stream of bytes (not ints) and there can be millions of bytes in the stream. The compacting works out.

    Strings - because a char is a byte, the conversion is 1 to 1.

    But for the most part, it sticks to ints. Don't worry so much about it.
     
    eisenpony likes this.
  7. grizzly

    grizzly

    Joined:
    Dec 5, 2012
    Posts:
    357
    In simple terms, 32bit processors handle 32bit integers natively. 32 being the number of bits per cycle. Smaller data types such as Int16 are treated as Int32 with the unused bits being masked out, processed, then converted back to Int16. An Int64 on a 32bit machine would require two cycles.

    Avoiding numeric casts would definitely be a good reason to stick with Int32.That's not to say that casts cannot be avoided however. The .NET "Math" library provides a full range of type overloads, including those for bytes.
     
    Last edited: Feb 14, 2016
    heu3becteh likes this.
  8. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    This is a micro optimization that won't matter much, just use int. If you are working with very large numbers and no negatives uint might be usefull to you.

    But really just profile and optimize where needed instead of worry about tiny as details like this.
     
    ericbegue likes this.
  9. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Please don't prematurely optimise, the bottlenecks you face probably won't be there.
     
    ericbegue and eisenpony like this.
  10. LovesSolvingProblems

    LovesSolvingProblems

    Joined:
    Jan 22, 2015
    Posts:
    17
    I/O to ram is extremely fast so I agree with everyone else that this won't be your bottleneck.

    Another consideration is that if you end up needing to change your game and a byte no longer is sufficient then you'll be doing some rework.

    A good rule of thumb is to write your code in the simplest easiest to read and understand way. Then at the end if you do have bottlenecks it will be easy to optimize.