Is this:
foreach(Type item in myCollection)
{
StringBuilder sb = new StringBuilder();
}
much slower than:
StringBuilder sb = new StringBuilder();
foreach(Type item in myCollection)
{
sb = new StringBuilder();
}
In other words, will it really matter where I declare my StringBuilder?
No, it will not matter performance-wise where you declare it.
For general code-cleanliness, you should declare it in the inner-most scope that it is used - ie. your first example.
You could maybe gain some performance, if you write this:
StringBuilder sb = new StringBuilder();
foreach(Type item in myCollection)
{
sb.Length = 0;
}
So you have to instantiate the StringBuilder just once and reset the size in the loop, which should be slightly faster than instantiating a new object.
In the 2nd example you're creating an extra instance of StringBuilder. Apart from that they are both they same, so the performance issue is negligable.
There isn't enough code here to clearly indicate a performance difference in your specific case. Having said that, the difference between declaring a reference variable inside of a loop like this vs. outside is trivial for most cases.
The effective difference between your two code samples is that the second will allocate 1 more instance of StringBuilder than the first. The performance impact of this as compared to the rest of your application is essentially nothing.
Best way to check is by trying both methods in a loop, about 100.000 each. Measure the amount of time each 100.000 iterations take and compare them. I don't think there is a lot of difference.
But there is a small difference, though. The first example will have as many variables as the number of iterations. The second example just has one variable. The compiler is smart enough to do some optimizations here, so you won't notice a speed improvement.
However, if you don't want to use the last object generated inside the loop once you're outside the loop again, then the first solution would be better. In the second solution, it just takes a while before the garbage collector will free the last object created. In the first example, the garbage collector will be a bit faster in freeing the object. It depends on the rest of the code but if you store a lot of data in this StringBuilder object then the second example might hold on to this memory a lot longer, thus decreasing the performance of your code after leaving the loop! Then again, if the objects eats up 100 KB and you have 16 GB in your machine, no one cares... The garbage collector will eventually free it again, probably as soon when you leave the method which contains this loop.
If you have other similar type code segments, you could always profile or put some timers around the code and run a benchmark type test to see for yourself. Another factor would be the memory footprint, which others have commented on.
Related
Context: I'm using Unity3D's IMGUI where OnGUI{} method is being called/update VERY often (few times per frame) to keep GUI content relevant. I need to iterate through Dictionary with data and display said data, but because I also will be making changes to Dictionary content (Add/Remove) I have to iterate through separate List/Array/whatever.
So in other words right now I have:
foreach (string line in new List<string>(this.myDic.Keys))
{
//fill GUI
//edit Dictionary content if needed
}
The problem here is that it allocates short-lived List multiple time per frame, thousands and thousands times per second and insane amount in general, producing GC. What I want is to avoid this allocation by reusing the same List I initialize at the start. However, another issue came up:
tempList.Clear();
foreach (KeyValuePair<string,string> pair in myDic)
{
tempList.Add(pair.key)
}
var j = tempList.Count;
for (int i = 0; i < j; i++)
{
//fill GUI
//edit Dictionary content if needed
}
As you can see now I basically have two loops, both processing same amount of data. Which leads me to the question: is it moot point here trying to optimize the allocation issue here with reusable List? Or may be even if it looks scary the double-loop variant still better solution?
P.S. Yes, I know, best option would be switch from IMGUI but right now I'm kinda limited to it.
First of all, the only object you allocate by calling new List<string>(this.myDic.Keys) (or this.myDic.Keys.ToArray() alternatively) is an array containing references to already existing objects (strings in your case). So, the GC collects only one object when the scope ends.
The size of that object is about equal to objectCount*referenceSize. The reference size depends on the selected platform: 32bit or 64bit.
Speaking formally, you can save some memory traffic by reusing an existing list, but I guess it's not worth it.
Anyway, if you're up to do that, please note that your approach to refilling the list isn't optimal. I suggest you using .AddRange (it internally uses Array.Copy).
tempList.Clear();
tempList.AddRange(myDic.Keys)
foreach (key in tempList) { ... } //replace with 'for' if you also want to avoid allocation of an iterator
Most likely it's a premature optimization, please do some performance benchmark to test if it makes any sense for your application.
I've got a few global arrays I use in a simple WinForms game. The arrays are initialized when a new game starts. When a player is in the middle of the game (the arrays are filled with data) he clicks on the StartNewGame() button (restarts the game). What to do next?
Is it ok to reinitialize the whole array for the new game or should I just set every array item to null and use the already initialized array (which would be slower)?
I mean is it okay to do something like this?
MyClass[,] gameObjects;
public Form1()
{
StartNewGame();
// game flow .. simplified here .. normally devided in functions and events..
StartNewGame();
// other game flow
}
public StartNewGame()
{
gameObjects = new MyClass[10,10];
// some work with gameObjects
}
This almost entirely depends upon MyClass, specifically how many data members it contains, how much processing does its constructor (and members' constructors) require and whether it is a relatively simply operation to (re)set an object of this class to "initialized" state. A more objective answer can be obtained through benchmarking.
From you question, I understand that there are not so many array's - in that case I would say, reinitialize the whole array
In cases you have a lot of work that can take 30 sec to set up maybe you do clean up instead of reinitializing everything.
If you choose to place null, you can jet some ugly exception , so I think you rather clean the object inside the array rather then set them to null
If there are only 100 elements as in your example, then there shouldn't really be a noticeable performance hit.
If you reinitialize the array, you will perform n constructions for n objects. The garbage collector will come clean up the old array and de-allocate those old n objects at some later time. (So you have n allocations upfront, and n deallocations by the GC).
If you set each pointer in the array to null, the garbage collector will still do the same amount of work and come clean up those n objects at some later time. The only difference is you're not deallocating the array here, but that single deallocation is negligible.
From my point of view, the best way to achieve performance in this case is to not reallocate the objects at all, but to use the same ones. Add a valid bit to mark whether or not an object is valid (in use), and to reinitialize you simply set all the valid bits to false. In a similar fashion, programs don't go through and write 0's to all your memory when it's not in use. They just leave it as garbage and overwrite data as necessary.
But again, if your number of objects isn't going into the thousands, I'd say you really won't notice the performance hit.
gameObjects = new MyClass[10,10];
... is the way to go. This is definitely faster than looping through the array and setting the items to null. It is also simpler to code and to understand. But both variants are very fast in anyway, unless you have tens of millions of entries! '[10, 10]' is very small, so forget about performance and do what seems more appropriate and more understandable to you. A clean coding is more important than performance in most cases.
Sorry for asking such a simple question but wanted to clear a concept.
Below is my code where I am creating a dictionary inside for loop
if(condition)
{
// some code here
for(int i=0; i<length; i++)
{
Dictionary<string, string> parameter = new Dictionary<string, string>();
parameter.Add("ServiceTypeID", "1");
parameter.Add("Description", "disc");
}
}
instead of creating dictionary object every time should I be creating the dictionary object before for loop and applying clear method on dictionary object like
if(condition)
{
Dictionary<string, string> parameter = new Dictionary<string, string>();
// some code here
for(int i=0; i<length; i++)
{
parameter.clear();
parameter.Add("ServiceTypeID", "1");
parameter.Add("Description", "disc");
}
}
Out of these two option which one will be better for performance.
Thanks,
nil
In most practical scenarios the difference is close to zero.
One may think that clearing a data structure is quicker than initializing an empty one. This is not always the case. Note that modern languages (C#, Java) the memory manager is optimized for allocating many small objects (this is related to the way Garbage Collectors work). In C++, due to the lack of a GC, the memory manager is tuned to allocation of few large objects. Thus, re-constructing the Dictionary inside the loop is comparable (performance-wise) with clearing it.
Moreover, clear() may not necessarily free all allocated memory. It can be that it only resets some pointers/indices. Therefore, if you use clear() your Dictionary may still occupy large chunks of memory which may slow down other parts of your code.
Bottom line: don't worry about it unless a profiler told you that this is the bottleneck of your program.
If both of these solutions are working for you you should remember two items :
first one creates dictionary object in each loop, so its speed is lower because of allocating memory in each loop times
second one is faster. but takes the Dictionary object alive for more time, so memory will be full if GC takes no action on it! (GC removes it after scope ends) so in long blocks of code, takes the memory in use for more time!
In few words for the performance, clearly, the second loop is better because you create only one object and then in the loop you add items.
However in the first loop parameter variable is not useful because at the end of the for it does not exists any more...
also in the second loop you have the same problem... at the end of the if that reference isn't usable....
which is better, performance-wise, when you potentially have an empty list?
if (_myList != null && _myList.Count > 0)
{
foreach (thing t in _myList )
{
...
or without checking if _myList count contains anything:
if (_myList != null)
{
foreach (thing t in _myList )
{
...
I'm guessing there's probably not much in it, but that the first one is slightly quicker (?)
Thanks
edit:
To clarify, I mean a list like this: List<Thing>
There is only one way to answer a performance question:
Measure
Measure
Measure
The only way you can know if:
I can improve the code
I have improved the code
And most importantly: What code to improve first
is to measure how much time different parts of the program is taking, and then improving the top items first.
To answer your question, I would assume that the miniscule overhead of a few extra objects is indeed going to cost you some cycles compared to just calling Count (assuming that is a fast call, field read for instance).
However, since you're asking this question it tells me that you don't have enough information about the state of your program and your code, so the chance of improving that miniscule overhead actually having a noticable effect for your users is so slim I wouldn't bother.
I can guarantee you have bigger fish to fry performance-wise, so tackle those first.
Personally I don't use null references except when dealing with databases or in a few lines of code to signal "not initialized yet", other than that I use empty lists and strings, etc. Your code is much easier to read and understand, and the benefit of microoptimization on this level will never be noticed.
Unless you are calling your code in a tight loop, the difference will be insignificant. However, be advised that there is a difference: the check for _myList.Count > 0 avoids the calling of GetEnumerator, the creation of an IEnumerator implementing object (a heap allocation) and a call to that enumerator's MoveNext() method.
If you are in a tight spot performance-wise that avoided (heap allocation + virtual method calls) might help, but in general your code is shorter and easier to understand by avoiding the explicit on _myList.Count.
Compulsory Disclaimer: You should have already identified this as a problem area via profiling before attempting to "optimise it", and hence you'll already have a the tools at hand to determine quickly and easily which methods faster. Odds are, neither will make an appreciable difference to your application's performance.
But that being said, Count, for System.Generics.Collection.List<> will almost definitely be quicker.
Although optimisation improves things greatly (don't be scared of using foreach! it's nearly free), foreach more or less involves:
var enumerator = _myList.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
}
}
finally
{
enumerator.Dispose();
}
which is a lot more complicated than merely comparing a simple property (safe assumption that List.Count is a simple property) with a constant.
Is there a way to find how much memory is used for a particular object? For example a List. Taking everything into account, like string interning and whatever is done by compiler/runtime environment/whatever.
ANTS Memory Profiler profiles the memory consumption of .NET code. I've had great results with it in the past.
You'd really have to define exactly what you meant by "how much memory is used for a particular object". For instance, you could mean "if this object were garbage collected, how much would be freed" - or you could mean "how much memory does this object and everything it touches take up."
Your point about string interning is a good example. Suppose you do:
List<string> internedStrings = new List<string>();
List<string> nonInternedStrings = new List<string>();
for (int i=0; i < 1000; i++)
{
string tmp = new string(' ', i+1);
nonInternedStrings.Add(tmp);
tmp = tmp.Intern();
internedStrings.Add(tmp);
}
Does nonInternedStrings really take up more memory than internedStrings? If internedStrings were garbage collected, it wouldn't free as much memory - but if internedStrings had never been created (including not interning each of its elements) then more memory would never have been required.
If you can be more specific about exactly what you mean, we may be able to help you. It's a complex issue though.
This seems to be a sibling of this Delphi question. A naive algorithm won't take into account the difference between aggregation and composition. Even an algorithm based on mark and sweep won't tell you whether a hash table had to grow its internal array because an object was referenced by it. You probably are better off profiling your application for a variety of scenarios and plotting the resource usage against N, where N is some measure of the scale of your dataset.
Have you tried CLR Profiler 2.0?