While writing some code where performance could be very important, one needs to be careful and be aware of what impact is going to be on performance because of every small peace of code we write.
Apart from getting these infos from msdn, what I do is try out the comparison between different alternatives I have and get the best for performance (considering memory and speed both).
Here are some info about performance issues along with the performance numbers
- Boxing Unboxing
This boxing/unboxing acts as a bridge between Value Types and Reference Types.
Boxing – storing Value type’s data into a Reference type.
Unboxing – Retrieving the data back from the reference type into a value type.
Example:
int i = 10;
object tmp = i; //int is boxed to object
int j = (int)tmp; //object is unboxed to int
When a value type is boxed the runtime need to copy the data, create a new reference to the data and then assign it to the object.
While unboxing the data is copied to the value type. The process of boxing and unboxing is said to be costly because it needs to create new objects which hits memory and speed as well.
The code above and the same code with “tmp” as int type were executed and the performance numbers found are below:
iteration count | output parameter | Code with Boxing/Unboxing | Code without Boxing/Unboxing |
1000 | Time (ms) | 0 | 0 |
Memory (bytes) | 8192 | 0 | |
10000 | Time (ms) | 0 | 0 |
Memory (bytes) | 115232 | 0 | |
100000 | Time (ms) | 0 | 0 |
Memory (bytes) | 148512 | 0 | |
1000000 | Time (ms) | 31.25 | 15.625 |
Memory (bytes) | 459748 | 0 | |
10000000 | Time (ms) | 218.75 | 46.875 |
Memory (bytes) | 461520 | 0 | |
100000000 | Time (ms) | 2265.625 | 468.75 |
Memory (bytes) | 445264 | 0 |
One scenario where this situation generally arises is using ArrayList or Hashtable where value types are to be stored. Since, ArrayList and Hashtable store them as object (reference type) there could be a significant impact on performance. Fortunately .Net 2.0 f/w provides Generics which gets rid of the boxing/unboxing headache.
Using List instead of ArrayList and Dictionary instead of Hashtable would show significant performance improvement.
Here is a sample test results:-
ArrayList and List were used for storing “int” values. The table below shows comparison results for different number of objects added and retrieved.
count of objects added | output parameter | ArrayList | List<int> | Difference (ArrayList – List<int>) |
1000 | Time (ms) | 0 | 0 | 0 |
Memory (bytes) | 16384 | 8192 | 8192 | |
10000 | Time (ms) | 0 | 0 | 0 |
Memory (bytes) | 245292 | 131168 | 114124 | |
100000 | Time (ms) | 15.625 | 0 | 15.625 |
Memory (bytes) | 2117280 | 1048768 | 1068512 | |
1000000 | Time (ms) | 187.5 | 31.25 | 156.25 |
Memory (bytes) | 16190760 | 6291540 | 9899220 | |
10000000 | Time (ms) | 3421.875 | 484.375 | 2937.5 |
Memory (bytes) | 187108224 | 100663380 | 86444844 |
However the same test for storing reference type objects showed more or less same speed and memory for obvious reasons (no boxing unboxing involved).
- Cost of relying on Exceptions
Some operations might throw exceptions if not used correctly.
For example, Opening a file which doesn’t exist.
The code could be written in 2 ways-
1.
try
{
DoSomeOperation(inputData);
//do something.
}
catch(InvalidInputException ex)
{
//handle invalid input
}
2.
if(IsValid(inputData))
{
DoSomeOperation(inputData);
//do something.
}
else
{
//handle invalid input data.
}
Both the codes do the same job i.e. do some operation on the specified input data, providing same results.
But the first one relies on Exception which is very costly and might hit performance significantly (for memory also because Exception objects are created to be thrown).
In cases where validity check itself is costly and chances are rare that you will have invalid input data, 1st one might be better performance wise.
Assuming that validity check is done in virtually no time (to make it simple to get the cost involved with exceptions) I have performed a test which shows the impact of relying on exceptions on performance.
iteration count | output parameter | Code with Exceptions handling | Safe Code with validaty check |
100 | Time (ms) | 734.375 | 0 |
Memory (bytes) | 16384 | 0 | |
1000 | Time (ms) | 7609.375 | 0 |
Memory (bytes) | 166952 | 0 | |
10000 | Time (ms) | 246234.375 | 0 |
Memory (bytes) | 107404 | 0 |