Consider this code:
var (mult, sum) = MultSum(a, b);
and
var (_, sum) = MultSum(a, b);
Question 1.
If I use discard instead of a variable name, does it have performance benefit? eg. by reducing assignment operations.
Question 2.
Is there any way to write the MultSum smart enough so it doesn't calculate the discards!?
If I use discard instead of a variable name, does it have performance benefit? eg. by reducing assignment operations.
In your particular case it is unlikely that there would be a benefit in performance. The tuple that is returned is assigned to temporary storage; you've just not given a name to one part of that storage.
Now, if you had an expression that had discards that were entire values, not fragments of a tuple, then the compiler and the jitter can be smart about not allocating any storage on the short-term pool for the result, or re-using existing storage that was already allocated. Note that by "short-term pool" I effectively mean "activation record on the stack" or "registers". This could, in theory, lead to better register allocation or smaller frames (and therefore better locality of reference) and that in turn could save you entire nanoseconds.
Nano-optimizations are generally not worth it; there is almost always a better bang-for-buck performance problem to attack. But if you think it might be relevant for your scenario, measure it and see. That is the only way to know if there is a relevant performance difference. Get out a nano-scale stopwatch, run the code both ways, and see which one is faster.
The benefit you should be attempting to accrue by using discards is the "make my program easier to understand" benefit. Programmers are expensive; optimize for making your code easy for future programmers to read, understand and modify.
Is there any way to write the MultSum smart enough so it doesn't calculate the discards!?
Yes. Write your program in Haskell. Haskell will avoid performing calculations whose results are never used. C# is not such a language.
Related
Which is better in accessing a property value?
Accessing like this
propertyobjA.objB.Prop1
propertyobjA.objB.Prop2
or assign to var
var objB = propertyobjA.objB;
then call objB.Prop1 and objB.Prop1
Which one improves performance in c#?
To be perfectly the honest, the answer is likely that the second will be faster, but I can pretty much guarantee that it will not matter in the slightest. You should be careful of thinking too hard about optimisation too early. 99% of all performance issues are down to much larger issues such as hitting a database too frequently, etc., not trivial issues like this. Even if there was a tiny difference between the two cases, unless this is some of the most time-critical software on the planet, what matters is readability (not that either are hard to read in this case), not which is faster.
It depends on what objB is. If you are calculating something (which you shouldn't do but can do) then of course assigning it to a value will yield better performance.
Another note, you should avoid having dependencies on sub properties of a variable, since you are putting a higher coupling between the classes.
I think this won't make a big difference performancewise (second alternative might be a bit faster). But this is not the place where your performance problems (if any) come from.
UPDATE: Thinking about, the value of propertyobjA.objB could change between getting Prop1 and Prop2, so the two alternatives cannot be considered as being the same code.
The impact to performance largely depends on the implementation of the propertyObjA.objB property getter. For instance, if it is simply implemented as:
public Foo objB { get { return this._objB; } }
Then calling that twice will have a negligible impact on performance.
If, however, that same property did something computationally expensive, then your second suggestion would perform better.
That being said, the framework guidelines state that you should not use property getters to hide potentially computationally expensive operations, instead preferring a method call instead, e.g.:
public objB ComputeB ();
You really ought to not concern yourself with things like that when writing code in a higher level language such as c#.
Modern compilers of such languages as c# and java are extremely sofisticated and will perform all kinds optimizations on your code. The end result for you as developer is that you will never see a difference in performance when writing a particular trivial piece of code one way or the other. The compiler will pick the most optimal way.
Everything else is down to preference. If you like to chain several property accesses, that's fine. If you like to assign an intermediate result to a variable to improve readability of your code, that's fine too.
There is an established guideline that getting a hashcode should not allocate memory because this will negatively impact hash table lookups by invoking the garbage collector.
Yet this exact failing is what I see what I profile my application which uses a System.Collections.Generic.Dictionary
Way deep down in a very tight loop I find the following in my profiler results:
[3.47%] TryGetValue(TKey, TValue&) (...Dictionary)
[3.47%] FindEntry(TKey) (...Dictionary)
[3.47%] GetHashCode(string) (System.CultureAwareComparer)
[3.46%] GetHashCodeOfString(String, CompareOptions) (System.Globalization.CompareInfo)
[3.39%] [Garbage Collection]
[0.01%] [Thread Suspendended]
That's the whole sub-tree accounting from the profiler.
I'm not a seasoned expert in this specific sort of work, so I could be reading these tea leaves incorrectly. But it looks to me like GetHashCodeOfString "must be" allocating memory and inviting the garbage collector to interrupt my program in the middle of this loop I want REALLY TUNED AND TIGHT, and this is accounting for the staggering majority of the cost of this loop.
As an aside, here is an additional piece of evidence suggesting this code allocates memory
My next step will be to initialize the Dictionary with the ordinal comparer and re-run my tests.
But I want to know if there is existing wisdom out there around this issue. It seems like dictionaries with string keys are common, and the costs of such a common thing may be well explored. I found the following analysis, but it focuses on the actual comparison as the cause for woe, and not the hash code method allocating memory.
Can anyone suggest the proper way to use a dictionary with string keys that avoids this problem?
Specific questions I have include:
If I use the ordinal comparitor will the allocation go away?
If not, do I need to write my own comparitor, and will THAT make the allocation go away?
If I do make the comparitor go away, can I really expect a real improvement, as per the MSFT recommendation link I started with?
EDIT: Crud, my bad, but this is not with the default comparer properties, we have it set to ignoreCase. Not sure if this impacts the results, but since ignoreCase would impact the equality, it must therefor have some impact on the hash.
UPDATE: Ran another test using the ordinal comparer (still with IgnoreCase), and recast the original results output to 100% cost = TryGetValue so it would be more apples to apples
Original:
100% TryGetValue
100% FindEntry
99.5% CultureAwareComparer.GetHashCode
99.5% CompareInfo.GetHashCodeOfString
95.86% [Garbage Collection]
3.31% [Thread Suspended]
0.5% CultureAwareComparer.Equals
0.5% Compare
0.5% [garbage collection]
Ordinal:
100% TryGetValue
100% FindEntry
47.22% CultureAwareComparer.Equals
47.22% [Garbage Collection]
There also appeared to be a dramatic decrease in the overall time spend in TryGetValue. I was not careful to make sure all else was equal, but this accounted for 46 seconds out of a 10 minute stress test in the first run, and in the orindal run it accounted for 252 milliseconds. Consider that anecdotal, not an expected relative cost.
It seems like the entire cost of the hash, which used to be 99+% of the cost, is now so "free" that it fails to even appear in the profiler, which I think is running in sampling mode.
I guess this seconds the word on the street that you should use ordinal comparison.
I still can't PROVE to myself why the GC cost is contributing so heavily to the first profile result, but from the comments below I suppose I have to believe it does NOT allocate managed heap memory, but that because it's slow, it tends to be the function that is "randomly" GCed by other activities on other threads, as this process is indeed using server mode gc.
Maybe this indicates that this tight loop tends to be concurrent with allocation-happy code someplace else.
By default, when you use string keys, string.GetHashCode() is used. This method doesn't allocate any memory on the heap, and should be pretty fast.
But since you're using ignore case, CultureAwareComparer.GetHashCode() is used instead. That method calls (as can be seen from your profile results) CompareInfo.GetHashCodeOfString(), which in turn calls the unmanaged function InternalGetGlobalizedHashCode(). Neither of the two managed methods makes any heap allocations (as you can see if you look at them in a decompiler). I can't say what InternalGetGlobalizedHashCode() does, but since it is unmanaged, I doubt it makes any allocations on the managed heap. In any case, it has to be quite a lot more complex than the default hash code computation, especially since it is culture-aware and has to keep in mind issues like the Turkish İ.
What this means is that you probably have some other code that allocates memory on the heap, which causes the garbage collection.
And if you are going for maximum performance, you should avoid “ignore case”, and especially its culture-aware variants.
The question is simple, which is faster between CalledOften1 and CalledOften2
class MyTest
{
public bool test = false;
void CalledOften1()
{
if (!test) test = true;
DoSomething();
}
void CalledOften2()
{
test = true;
DoSomething();
}
}
Is the compiler optimized (if possible) to avoid future assignments of test if it's already true?
UPDATE:
This question is just an information, I will not use the if (bla) style if I can write test=true, I prefer code readability.
I prefer to measure for these sorts of questions rather than guess:
CalledOften1: 52 million operations per second
CalledOften2: 53 million operations per second
So they are nearly the same. If anything, the simpler method is also the faster.
This is a perfect example of premature optimization.
If you want to set test to true every time, just set it. Don't complicate your code for a theorized speedup.
That being said, the reduced instruction set of the second example, along with being simpler and more maintainable, is most likely faster due to avoiding the branching and reducing the number of instructions. A single assignment of a bool is a very fast operation. If you really need to know how much faster it may be, I would profile this yourself. However, I suspect that either would be fast enough in any case.
I would expect the second version to be slightly faster, given that it doesn't involve any branching. It also expresses the intention of "make sure the variable is true, whatever it was before" more clearly IMO. However:
I doubt that it's significant
Any number of actual changes in context could make the results change (including your code, or the version of the framework you're running against)
Write the clearest code first, and optimize later
Benchmark this against your real code, under realistic conditions before you decide to change anything
Compiler optimizes only something that is definite at compile time. This is changed at runtime so answer is no. Compiler could optimize if you were checking against constant. CalledOften1 is faster, but the magnitude is so small that you would not notice. This is kind of microptimisation you should avoid.
If I had to guess, I would say that CalledOften2 is more optimized, as there is no logic test operation done.
In the end, if you are looking at this level of optimization, then your application will probably go as fast as it can. Any performance gain you get out of this type of optimization will likely never be noticed by anyone.
My two cents,
Brian
Premature optimization is the root of all evil. Use the one that expresses your intent most clearly.
(I'm guessing a read+branch is going to be more expensive than just a write, but don't really know the CLR. The important thing is that computers are increasing in speed exponentially, and programmers aren't. Algorithmic improvements in performance bottlenecks are worth exploring, barely measurable constant-time improvements for their own sake aren't.)
If I have the following function, it is considered pure in that it has no side effects and will always produce the same result given the same input x.
public static int AddOne(int x) { return x + 1; }
As I understand it, if the runtime understood the functional purity it could optimize execution so that return values wouldn't have to be re-calculated.
Is there a way to achieve this kind of runtime optimization in C#? And I assume there is a name for this kind of optimization. What's it called?
Edit: Obviously, my example function wouldn't have a lot of benefit from this kind of optimization. The example was given to express the type of purity I had in mind rather than the real-world example.
As others have noted, if you want to save on the cost of re-computing a result you've already computed, then you can memoize the function. This trades increased memory usage for increased speed -- remember to clear your cache occasionally if you suspect that you might run out of memory should the cache grow without bound.
However, there are other optimizations one can perform on pure functions than memoizing their results. For example, pure functions, having no side effects, are usually safe to call on other threads. Algorithms which use a lot of pure functions can often be parallelized to take advantage of multiple cores.
This area will become increasingly important as massively multi-core machines become less expensive and more common. We have a long-term research goal for the C# language to figure out some way to take advantage of the power of pure functions (and impure but "isolated" functions) in the language, compiler and runtime. But doing so involves many difficult problems, problems about which there is little consensus in industry or academia as to the best approach. Top minds are thinking about it, but do not expect any major results any time soon.
if the calculation was a costly one, you could cache the result in a dictionary?
static Dictionary<int, int> cache = new Dictionary<int, int>();
public static int AddOne(int x)
{
int result;
if(!cache.TryGetValue(x, out result))
{
result = x + 1;
cache[x] = result;
}
return result;
}
of course, the dictionary lookup in this case is more costly than the add :)
There's another much cooler way to do functional memoization explained by Wes Dyer here: http://blogs.msdn.com/wesdyer/archive/2007/01/26/function-memoization.aspx - if you do a LOT of this caching, then his Memoize function might save you a lot of code...
I think you're looking for functional memoization
The technique you are after is memoization: cache the results of execution, keyed off the arguments passed in to the function, in an array or dictionary. Runtimes do not tend to apply it automatically, although there are certainly cases where they would. Neither C# nor .NET applies memoization automatically. You can implement memoization yourself - it's rather easy -, but doing so is generally useful only for slower pure functions where you tend to repeat calculations and where you have enough memory.
This will probably be inlined (aka inline expansion) by the compiler ...
Just make sure you compile your code with the "Optimize Code" flag set (in VS : project properties / build tab / Optimize Code)
The other thing you can do is to cache the results (aka memoization). However, there is a huge initial performance hit due to your lookup logic, so this is interesting only for slow functions (ie not an int addition).
There is also a memory impact, but this can be managed through a clever use of weak references.
As I understand it, if the runtime
understood the functional purity it
could optimize execution so that
return values wouldn't have to be
re-calculated.
In your example, the runtime WILL have to compute the result, unless x is known at compile time. In that case, your code will be further optimized through the use of constant folding
How could the compiler do that ? How does it know what values of x are going to be passed in at runtime?
and re: other answers that mention inlining...
My understanding is that inlining (as an optimization) is warranted for small functions that are used only once (or only a very few times...) not because they have no side effects...
A compiler can optimize this function through a combination of inlining (replacing a function call with the body of that function at the call site) and constant propagation (replacing an expression with no free variables with the result of that expression). For example, in this bit of code:
AddOne(5);
AddOne can be inlined:
5 + 1;
Constant propagation can then simplify the expression:
6;
(Dead code elimination can then simplify this expression even further, but this is just an example).
Knowing that AddOne() has no side effects might also enable the a compiler to perform common subexpression elimination, so that:
AddOne(3) + AddOne(3)
may be transformed to:
int x = AddOne(3);
x + x;
or by strength reduction, even:
2*AddOne(3);
There is no way to command the c# JIT compiler to perform these optimizations; it optimizes at its own discretion. But it's pretty smart, and you should feel comfortable relying on it to perform these sorts of transformations without your intervention.
Another option is to use a fody plugin https://github.com/Dresel/MethodCache
you can decorate methods that should be cached. When using this you should of course take into consideration all the comments mentioned in the other answers.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I am wondering what kind of optimization techniques people often use nowadays. I have seen people do caching all the time with dictionary and all. Is the trading space for speed the only way to go?
Really it's about your choice in algorithms. Usually there is no "silver bullet" for optimization.
For example, using a StringBuilder instead of concatenation can make your code significantly faster, but there is a tradeoff. If you aren't concatenating huge sets of strings, the memory and time it takes to initialize StringBuilder is worse than just using regular concatenation. There are a lot of examples of this throughout the framework, such as dictionary caching as you mentioned in your question.
The only general optimization you can really learn and apply to your coding throughout your day is the performance hit from boxing/unboxing (heap vs. stack). To do this you need to learn what it's about and how to avoid, or reduce the need to do it.
Microsoft's MSDN documentation has 2 articles on performance that give a lot of good general purpose techniques to use (they're really just different versions of the same article).
http://msdn.microsoft.com/en-us/library/ms173196.aspx
http://msdn.microsoft.com/en-us/library/ms173196(VS.80).aspx
I will suggest below
1. Knowing when to use StringBuilder
You must have heard before that a StringBuilder object is much faster at appending strings together than normal string types.
The thing is StringBuilder is faster mostly with big strings. This means if you have a loop that will add to a single string for many iterations then a StringBuilder class is definitely much faster than a string type.
However if you just want to append something to a string a single time then a StringBuilder class is overkill. A simple string type variable in this case improves on resources use and readability of the C# source code.
Simply choosing correctly between StringBuilder objects and string types you can optimize your code.
2. Comparing Non-Case-Sensitive Strings
In an application sometimes it is necessary to compare two string variables, ignoring the cases. The tempting and traditionally approach is to convert both strings to all lower case or all upper case and then compare them, like such:
str1.ToLower() == str2.ToLower()
However repetitively calling the function ToLower() is a bottleneck in performace. By instead using the built-in string.Compare() function you can increase the speed of your applications.
To check if two strings are equal ignoring case would look like this:
string.Compare(str1, str2, true) == 0 //Ignoring cases
The C# string.Compare function returns an integer that is equal to 0 when the two strings are equal.
3. Use string.Empty
This is not so much a performance improvement as it is a readability improvement, but it still counts as code optimization. Try to replace lines like:
if (str == "")
with:
if (str == string.Empty)
This is simply better programming practice and has no negative impact on performance.
Note, there is a popular practice that checking a string's length to be 0 is faster than comparing it to an empty string. While that might have been true once it is no longer a significant performance improvement. Instead stick with string.Empty.
4. Replace ArrayList with List<>
ArrayList are useful when storing multiple types of objects within the same list. However if you are keeping the same type of variables in one ArrayList, you can gain a performance boost by using List<> objects instead.
Take the following ArrayList:
ArrayList intList = new ArrayList();
intList.add(10);
return (int)intList[0] + 20;
Notice it only contains intergers. Using the List<> class is a lot better. To convert it to a typed List, only the variable types need to be changed:
List<int> intList = new List<int>();
intList.add(10)
return intList[0] + 20;
There is no need to cast types with List<>. The performance increase can be especially significant with primitive data types like integers.
5. Use && and || operators
When building if statements, simply make sure to use the double-and notation (&&) and/or the double-or notation (||), (in Visual Basic they are AndAlso and OrElse).
If statements that use & and | must check every part of the statement and then apply the "and" or "or". On the other hand, && and || go thourgh the statements one at a time and stop as soon as the condition has either been met or not met.
Executing less code is always a performace benefit but it also can avoid run-time errors, consider the following C# code:
if (object1 != null && object1.runMethod())
If object1 is null, with the && operator, object1.runMethod()will not execute. If the && operator is replaced with &, object1.runMethod() will run even if object1 is already known to be null, causing an exception.
6. Smart Try-Catch
Try-Catch statements are meant to catch exceptions that are beyond the programmers control, such as connecting to the web or a device for example. Using a try statement to keep code "simple" instead of using if statements to avoid error-prone calls makes code incredibly slower. Restructure your source code to require less try statements.
7. Replace Divisions
C# is relatively slow when it comes to division operations. One alternative is to replace divisions with a multiplication-shift operation to further optimize C#. The article explains in detail how to make the conversion.
REFERENCE
There are often problems with algorithms as well, usually when something expensive is done inside of a loop. Generally, the first thing you do is profile your application, which will tell you the slowest part(s) of the application. Generally, what you do to speed up your application depends upon what you find. For example, if your application mimics a file system, it may be that you're calling the database recursively to travel up the tree (for instance). You may optimise that case by changing those recursive calls into one flattened database call that returns all of the data in one call.
Again, the answer is, as always, 'it depends'. However, more examples and advice can be found in Rico Mariani's blog (browse back a few years, as his focus has shifted):
Depends on a lot of things, really.
As an example, when memory becomes an issue and a lot of temporary objects are being created I tend to use object pools. (Having a garbage-collector is not a reason to not take care of memory allocation). If speed is what matters then I might use unsafe pointers to work with arrays.
Either way, if you find yourself struggling too much with optimization techniques in a c#/.net application you probably chose the wrong language/platform.
In general, make sure you understand the time complexity of different algorithms, and use that knowledge to choose your implementations wisely.
For .NET in particular, this article goes into great detail about optimizing code deployed to the CLR (though it's also relevant for Java, or any other modern platform), and is one of the best guides I've ever read:
http://msdn.microsoft.com/en-us/library/ms973852.aspx
To distill the article into one sentence: Nothing affects the speed of a .NET application (with sensible algorithms) more than the memory-footprint of its objects. Be very careful to minimize your memory consumption.
I would recommend Effective C# by Bill Wagner (first edition and second edition). He goes through a number of language constructs and techniques and explains which ones are faster and why. He touches on a lot of best practices as well.
More often than not, however, optimizing your algorithm will give you far better results than using any kind of language / optimization technique.