In C#, would there be any difference in performance when comparing the following THREE alternatives?
ONE
void ONE(int x) {
if (x == 10)
{
int y = 20;
int z = 30;
// do other stuff
} else {
// do other stuff
}
}
TWO
void TWO(int x) {
int y;
int z;
if (x == 10)
{
y = 20;
z = 30;
// do other stuff
} else {
// do other stuff
}
}
THREE
void THREE(int x) {
int y = 20;
int z = 30;
if (x == 10)
{
// do other stuff
} else {
// do other stuff
}
}
All else being equal (and they usually aren't, which is why you normally have to actually test it), ONE() and TWO() should generate the same IL instructions since local variables end up scoped to the whole method. THREE() will be negligibly slower if x==10 since the other two won't bother to store the values in the local variables.
All three take up the same amount of memory—the memory for all variables is allocated even if nothing is stored in them. The JIT compiler may perform an optimization here, though, if it ever looks for unused variables.
There no performance difference, but you're going to find variable scope issues between each of those examples.
You're also showing three different intents between those examples, which isn't what you want:
y and z are limited to the scope of the if statement.
y and z are used outside of the if statement, but are set conditionally.
y and z have nothing to do with the if statement whatsoever.
Of course, you should always pick ONE, it is much more readable. That it is faster by a fraction of a nanosecond isn't an accident, readable code often is.
I don't think it'll make much difference. The only time you would need to worry is if creating the new object and initializing it is expensive. You could always try to profile each method a couple thousand times to see if there are any differences but I doubt you'll find any.
The only time I move a declaration further away from where it's used is if it'll be worked on in a loop. e.g.:
void RunMethod() {
FormRepresentation formRep = null;
for (int idx = 0; idx < 10; idx++) {
formRep = new FormRepresentation();
// do something
}
}
It doesn't actually make any difference since the object is still being created but, to me, it looks cleaner. The other thing you need to consider is the scope of the variable. Declared variables cannot be used outside the scope they were declared in.
Related
When I have a readonly variable:
public readonly bool myVar = true;
And check it in a code like this:
for(int i = 0; i != 10; i++)
{
if(myVar)
DoStuff();
else
DoOtherStuff();
}
Looking at emitted IL, I can see that the check is performed on each iteration of the loop. I would expect the code above to produce the same IL as this:
if (myVar)
{
for(int i = 0; i != 10; i++)
{
DoStuff();
}
}
else
{
for(int i = 0; i != 10; i++)
{
DoOtherStuff();
}
}
So why isn't the check optimised to the outside of the loop, since the field is readonly and can't be changed between iterations?
Your proposed optimization really is a combination of two individual simpler transformations. First is pulling the member access outside the loop. From
for(int i = 0; i != 10; i++)
{
var localVar = this.memberVar;
if(localVar)
DoStuff();
else
DoOtherStuff();
}
to
var localVar = this.memberVar;
for(int i = 0; i != 10; i++)
{
if(localVar)
DoStuff();
else
DoOtherStuff();
}
The second is interchanging the loop condition with the if condition. From
var localVar = this.memberVar;
for(int i = 0; i != 10; i++)
{
if(localVar)
DoStuff();
else
DoOtherStuff();
}
to
var localVar = this.memberVar;
if (localVar) {
for(int i = 0; i != 10; i++)
DoStuff();
}
else {
for(int i = 0; i != 10; i++)
DoOtherStuff();
}
The first one is influenced by readonly. To do it, the compiler has to prove that memberVar cannot change inside the loop, and readonly guarantees this1 -- even though this loop could be called inside a constructor, and the value of memberVar could be changed in the constructor after the loop ends, it cannot be changed in the loop body -- DoStuff() is not a constructor of the current object, neither is DoOtherStuff(). Reflection does not count, while it may be possible to use Reflection to break invariants, it isn't permitted to do so. Threads do count, see footnote.
The second is a simple transformation but a more difficult decision for the compiler to make, because it's difficult to predict whether it will actually improve performance. Naturally you can look at it separately by doing the first transformation on the code yourself, and seeing what code is generated.
Perhaps a more important consideration is that in .NET, the optimization pass takes place in between MSIL and machine code, not during compilation of C# to IL. So you cannot see what optimizations are being done by looking at the MSIL!
1 Or does it? The .NET memory model is considerably more forgiving than e.g. the C++ model where any data race leads very quickly to undefined behavior unless the object is defined volatile/atomic. What if this loop runs in a worker thread spawned from the object constructor, and after spawning the thread, the constructor goes on (which I'll call the "second half") to change the readonly member? Does the memory model require that change to be seen by the worker thread? What if DoStuff() and the second half of the constructor force memory fences, for example access other members which are volatile, or take a lock? So readonly would only allow the optimization in a single-threaded environment.
Because it can be changed using Reflection:
using System;
using System.Reflection;
public class Program
{
public static void Main()
{
var t = new Test();
var field = typeof(Test).GetField("myVar", BindingFlags.Instance | BindingFlags.Public);
Console.WriteLine(t.myVar); // prints True
field.SetValue(t, false);
Console.WriteLine(t.myVar); // prints False
// Trying to use t.myVar = false or true; <-- does not compile
}
}
public class Test
{
public readonly bool myVar = true;
}
Working Fiddle: https://dotnetfiddle.net/W9UO3m
Note there is no way in which the compile time code optimizer can predict or detect with absolute certainty whether or not such reflection code exists, and if it exists, if it will run or not.
A readonly field can be initialized to different values at different points in the code (multiple constructors). It can't be optimized out because multiple constructors allow for multiple values of the field in question.
Now, if you only had one constructor, with no relevant branching, and therefore only one possible value, ever, for that field, I'd expect more from the optimizer. However, that sort of analysis is one reason that C++ takes much longer to compile than C#, and these sorts of tasks aren't typically delegated to the runtime.
For a clearer explanation:
Note
The readonly keyword is different from the const keyword. A const
field can only be initialized at the declaration of the field. A
readonly field can be assigned multiple times in the field declaration
and in any constructor. Therefore, readonly fields can have different
values depending on the constructor used. Also, while a const field is
a compile-time constant, the readonly field can be used for run-time
constants as in the following example:
See https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/readonly
For your specific case, I'd suggest using const instead of readonly, though admittedly I haven't looked for differences in the generated IL.
Honestly, I'm wondering if it really makes a difference. Any CPU that performs branch prediction and has a halfway-decent cache will likely yield the same performance in either case. (Note that I haven't tested that; it's just a suspicion.)
Been bouncing back and forth between Swift and C# and I'm not sure if I'm forgetting certain things, or if C# just doesn't easily support what I'm after.
Consider this code which calculates the initial value for Foo:
// Note: This is a field on an object, not a local variable.
int Foo = CalculateInitialFoo();
static int CalculateInitialFoo() {
int x = 0;
// Perform calculations to get x
return x;
}
Is there any way to do something like this without the need to create the separate one-time-use function and instead use an instantly-executing lambda/block/whatever?
In Swift, it's simple. You use a closure (the curly-braces) that you instantly execute (open and closed parentheses), like this:
int Foo = {
int x = 0
// Perform calculations to get x
return x
}()
It's clear, concise and doesn't clutter up the object's interface with functions just to initialize fields.
Note: To be clear, I do NOT want a calculated property. I am trying to initialize a member field which requires multiple statements to do completely.
I wouldn't suggest doing this, but you could use an anonymous function to initialize
int _foo = new Func<int>(() =>
{
return 5;
})();
Is there a reason you would like to do it using lambdas rather than named functions, or as a calculated property?
I assume you want to avoid calculated properties because you want to either modify the value later, or the computation is expensive and you want to cache the value.
int? _fooBacking = null;
int Foo
{
get
{
if (!_fooBacking.HasValue)
{
_fooBacking = 5;
}
return _fooBacking.Value;
}
set
{
_fooBacking = value;
}
}
This will use what you evaluate in the conditional the first time it is gotten, while still allowing the value to be assigned.
If you remove the setter it will turn it into a cached calculation. Be careful when using this pattern, though. Side-effects in property getters will be frowned upon because they make the code difficult to follow.
To solve the problem in the general case you'd need to create and then execute an anonymous function, which you can technically do as an expression:
int Foo = new Func<int>(() =>
{
int x = 0;
// Perform calculations to get x
return x;
})();
You can clean this up a bit by writing a helper function:
public static T Perform<T>(Func<T> function)
{
return function();
}
Which lets you write:
int Foo = Perform(() =>
{
int x = 0;
// Perform calculations to get x
return x;
});
While this is better than the first, I think it's pretty hard to argue that either is better than just writing a function.
In the non-general case, many specific implementations can be altered to run on a single line rather than multiple lines. Such a solution may be possible in your case, but we couldn't possibly say without knowing what it is. There will be cases where this is possible but undesirable, and cases where this may actually be preferable. Which are which is of course subjective.
You could initialize your field in the constructor and declare CalculateInitialFoo as local function.
private int _foo;
public MyType()
{
_foo = CalculateInitialFoo();
int CalculateInitialFoo()
{
int x = 0;
// Perform calculations to get x
return x;
}
}
This won't change your code too much but you can at least limit the scope of the method to where it's only used.
I am making an OS with Cosmos and want to use goto to go to the user input but I am getting the error
No such label 'input' within the scope of the goto statement
'input' is a variable in which the user has inputted.
I can understand why this is happening but how do I fix it?
You cannot user variables as scope identifier for goto statement.. you have to use label identifier within scope (namespace) indicating it by ":" ..
for example
using System;
class Program
{
static void Main()
{
Console.WriteLine(M());
}
static int M()
{
int dummy = 0;
for (int a = 0; a < 10; a++)
{
for (int y = 0; y < 10; y++) // Run until condition.
{
for (int x = 0; x < 10; x++) // Run until condition.
{
if (x == 5 &&
y == 5)
{
goto Outer;
}
}
dummy++;
}
Outer:
continue;
}
return dummy;
}
}
method M contains three nested loops. The first loop iterates through numbers [0, 9], as do the two inner loops. But in the third loop, a condition is checked that causes the loop to exit using the break keyword.
For
Break
The code increments the dummy variable after each completion of the inner loop. If the inner loop is exited early, this variable should be left alone. With the goto statement, it is not incremented.
Result:
The value 50 is printed to the console. The int is incremented 10 x 5 times.
However:
If the goto was a break, the result would be 10 x 10 times, or a total of 100.
Hope this Help.. :)
I am making an OS with Cosmos
For getting any remotely useful answers, I think you will have to give some information about the scope of the OS. Are you only fiddling around with COSMOS a bit, or do you have some special use-case you want to serve with a custom COSMOS OS?
and want to use goto to go to the user input
Especially in the latter case (specialized OS) you should clearly refrain from using GOTO, unless you have a very good reason to do so (and in my humble opinion there is no such thing as a really good reason to use GOTO). There are viable alternatives to GOTOs in modern programming languages and you should re-think your design, algorithm, whatsoever.
To answer your question. Here is an example that produces the very error message you are experiencing
private void FirstMethod()
{
goto MyLabel;
}
private void SecondMethod()
{
MyLabel:
return;
}
I have defined a label in Method. Anyway, from Main you cannot simply jump from main to another method, since the compiler would not know where to return to, after the method has finished, since no data would have been pushed to the call stack on GOTO (please see the Wikipedia page about the call stack for further information).
The following, anyway, would work, since the label and the GOTO live within the same scope
void MyMethod()
{
goto MyLabel;
// do something
MyLabel:
return;
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Child Scope & CS0136
C# Variable Scoping
Though I have been using C# for quite some time, I have just stumbled upon this error.
If I have the following:
if(true)
{
int x = 0;
}
int x = 0;
I get an error that says: A local variable named 'x' cannot be declared in this scope because it would give a different meaning to 'x', which is already used in a child scope to denote something else.
And if I do this:
if(true)
{
int x = 0;
}
x = 0;
I get an error that says: The name 'x' does not exist in the current context.
I can understand having one or the other, but why do both of these errors exist? Is there a way around the first option? I find it very annoying.
Thanks.
Both of these errors exist to stop you from making mistakes or causing your colleagues to want to kill you.
The first fails because it's confusing to have two identically named local variables both in scope at a time.
The second fails because the variable's scope is the if statement, and you're trying to access it outside that scope.
If you want a single variable which you can use both inside and outside the block, you just need to declare it before the block:
int x;
if (true)
{
x = 0;
}
x = 0;
If you actually want two separate variables to be in scope at the same time (within the block), then give them different names - thereby avoiding later confusion.
EDIT: You can declare multiple local variables with the same name in a single method, but they have to have separate scopes. For example:
public void Foo(IEnumerable<string> values)
{
double sum = 0;
foreach (string x in values)
{
int z = x.Length;
sum += z;
}
foreach (string x in values)
{
double z = double.Parse(x);
sum += z;
}
}
Personally I don't tend to use this ability very often - at least not with different types - when the variables have meaningful names and methods are short. But it's absolutely legitimate, and can certainly be useful sometimes.
In the first case, the problem is that your int x outside the { } block has a global scope that encloses the context inside { }; therefore you are re-declaring a variable with the same name.
In the second case; x does not exist as it is only defined inside { }
for (var keyValue = 0; keyValue < dwhSessionDto.KeyValues.Count; keyValue++)
{...}
var count = dwhSessionDto.KeyValues.Count;
for (var keyValue = 0; keyValue < count; keyValue++)
{...}
I know there's a difference between the two, but is one of them faster than the other? I would think the second is faster.
Yes, the first version is much slower. After all, I'm assuming you're dealing with types like this:
public class SlowCountProvider
{
public int Count
{
get
{
Thread.Sleep(1000);
return 10;
}
}
}
public class KeyValuesWithSlowCountProvider
{
public SlowCountProvider KeyValues
{
get { return new SlowCountProvider(); }
}
}
Here, your first loop will take ~10 seconds, whereas your second loop will take ~1 second.
Of course, you might argue that the assumption that you're using this code is unjustified - but my point is that the right answer will depend on the types involved, and the question doesn't state what those types are.
Now if you're actually dealing with a type where accessing KeyValues and Count is cheap (which is quite likely) I wouldn't expect there to be much difference. Mind you, I'd almost always prefer to use foreach where possible:
foreach (var pair in dwhSessionDto.KeyValues)
{
// Use pair here
}
That way you never need the count. But then, you haven't said what you're trying to do inside the loop either. (Hint: to get more useful answers, provide more information.)
it depends how difficult it is to compute dwhSessionDto.KeyValues.Count if its just a pointer to an int then the speed of each version will be the same. However, if the Count value needs to be calculated, then it will be calculated every time, and therefore impede perfomance.
EDIT -- heres some code to demonstrate that the condition is always re-evaluated
public class Temp
{
public int Count { get; set; }
}
static void Main(string[] args)
{
var t = new Temp() {Count = 5};
for (int i = 0; i < t.Count; i++)
{
Console.WriteLine(i);
t.Count--;
}
Console.ReadLine();
}
The output is 0, 1, 2 - only !
See comments for reasons why this answer is wrong.
If there is a difference, it’s the other way round: Indeed, the first one might be faster. That’s because the compiler recognizes that you are iterating from 0 to the end of the array, and it can therefore elide bounds checks within the loop (i.e. when you access dwhSessionDTo.KeyValues[i]).
However, I believe the compiler only applies this optimization to arrays so there probably will be no difference here.
It is impossible to say without knowing the implementation of dwhSessionDto.KeyValues.Count and the loop body.
Assume a global variable bool foo = false; and then following implementations:
/* Loop body... */
{
if(foo) Thread.Sleep(1000);
}
/* ... */
public int Count
{
get
{
foo = !foo;
return 10;
}
}
/* ... */
Now, the first loop will perform approximately twice as fast as the second ;D
However, assuming non-moronic implementation, the second one is indeed more likely to be faster.
No. There is no performance difference between these two loops. With JIT and Code Optimization, it does not make any difference.
There is no difference but why you think that thereis difference , can you please post your findings?
if you see the implementation of insert item in Dictionary using reflector
private void Insert(TKey key, TValue value, bool add)
{
int freeList;
if (key == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
if (this.buckets == null)
{
this.Initialize(0);
}
int num = this.comparer.GetHashCode(key) & 0x7fffffff;
int index = num % this.buckets.Length;
for (int i = this.buckets[index]; i >= 0; i = this.entries[i].next)
{
if ((this.entries[i].hashCode == num) && this.comparer.Equals(this.entries[i].key, key))
{
if (add)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
}
this.entries[i].value = value;
this.version++;
return;
}
}
if (this.freeCount > 0)
{
freeList = this.freeList;
this.freeList = this.entries[freeList].next;
this.freeCount--;
}
else
{
if (this.count == this.entries.Length)
{
this.Resize();
index = num % this.buckets.Length;
}
freeList = this.count;
this.count++;
}
this.entries[freeList].hashCode = num;
this.entries[freeList].next = this.buckets[index];
this.entries[freeList].key = key;
this.entries[freeList].value = value;
this.buckets[index] = freeList;
this.version++;
}
Count is a internal member to this class which is incremented each item you insert an item into dictionary
so i beleive that there is no differenct at all.
The second version can be faster, sometimes. The point is that the condition is reevaluated after every iteration, so if e.g. the getter of "Count" actually counts the elements in an IEnumerable, or interogates a database /etc, this will slow things down.
So I'd say that if you dont affect the value of "Count" in the "for", the second version is safer.