I recall having read somewhere that it is better (in terms of performance) to use Int32, even if you only require Byte. It applies (supposedly) only to cases where you do not care about the storage. Is this valid?
For example, I need a variable that will hold a day of week. Do I
Guys, I am aware of DayOfWeek enum. The question is about something else.
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Usually yes, a 32 bit integer will perform slightly better because it is already properly aligned for native CPU instructions. You should only use a smaller sized numeric type when you actually need to store something of that size.
You should use the DayOfWeek enum, unless there’s a strong reason not to.
DayOfWeek day = DayOfWeek.Friday;
To explain, since I was downvoted:
The correctness of your code is almost always more critical than the performance, especially in cases where we’re talking this small of a difference. If using an enum or a class representing the semantics of the data (whether it’s the DayOfWeek enum, or another enum, or a Gallons or Feet class) makes your code clearer or more maintainable, it will help you get to the point where you can safely optimize.
int z; int x = 3; int y = 4; z = x + y;
That may compile. But there’s no way to know if it’s doing anything sane or not.
Gallons z; Gallons x = new Gallons(3); Feet y = new Feet(4); z = x + y;
This won’t compile, and even looking at it it’s obvious why not – adding Gallons to Feet makes no sense.
My default position is to try to use strong types to add constraints to values – where you know those in advance. Thus in your example, it may be preferable to use
byte dayOfWeek because it is closer to your desired value range.
Here is my reasoning; with the example of storing and passing a year-part of a date. The year part – when considering other parts of the system that include SQL Server DateTimes, is constrained to 1753 through to 9999 (note C#’s possible range for DateTime is different!) Thus a
short covers my possible values and if I try to pass anything larger the compiler will warn me before the code will compile. Unfortunately, in this particular example, the C# DateTime.Year property will return an int – thus forcing me to cast the result if I need to pass e.g.
DateTime.Now.Year into my function.
This starting-position is driven by considerations of long-term storage of data, assuming ‘millions of rows’ and disk space – even though it is cheap (it is far less cheap when you are hosted and running a SAN or similar).
In another DB example, I will use smaller types such as byte (SQL Server tinyint) for lookup ID’s where I am confident that there will not be many lookup types, through to long (SQL Server bigint) for id’s where there are likely to be more records. i.e. to cover transactional records.
So my rules of thumb:
- Go for correctness first if possible. Use DayOfWeek in your example, of course 🙂
- Go for a type of appropriate size thus making use of compiler safety checks giving you errors at the earliest possible time;
- …but offset against extreme performance needs and simplicity, especially where long-term storage is not involved, or where we are considering a lookup (low row count) table rather than a transactional (high row count) one.
In the interests of clarity, DB storage tends not to shrink as quickly as you expect by shrinking column types from bigint to smaller types. This is both because of padding to word boundaries and page-size issues internal to the DB. However, you probably store every data item several times in your DB, perhaps through storing historic records as they change, and also keeping the last few days of backups and log backups. So saving a few percent of your storage needs will have long term savings in storage cost.
I have never personally experienced issues where the in-memory performance of bytes vs. ints has been an issue, but I have wasted hours and hours having to reallocate disk space and have live servers entirely stall because there was no one person available to monitor and manage such things.
Use an int. Computer memory is addressed by “words,” which are usually 4 bytes long. What this means is that if you want to get one byte of data from memory, the CPU has to retrieve the entire 4-byte word from RAM and then perform some extra steps to isolate the single byte that you’re interested in. When thinking about performance, it will be a lot easier for the CPU to retrieve a whole word and be done with it.
Actually in all reality, you won’t notice any difference between the two as far as performance is concerned (except in rare, extreme circumstances). That’s why I like to use int instead of byte, because you can store bigger numbers with pretty much no penalty.
Most of the time use int. Not for performance but simplicity.
In terms of storage amount, use
byte and in terms of cpu performance, use