Question

I have the following method

void DoSome(){
    if (int.Parse(SomeStringProperty) > 8)
        // do something

    if (int.Parse(SomeStringProperty) < 10)
        // do something
}

Does the JIT know to keep the parsed value or is it better to do the following:

void DoSome(){
    var x = int.Parse(SomeStringProperty);
    if (x > 8)
        // do something

    if (x < 10)
        // do something
}

There is two optimizes the I can see here:

  1. The JIT automatically will do something like the second example
  2. The JIT do the one optimization and cache the result

My question its just about the one optimization that will need to be consistent and not about the 2 optimization that can be depending in a lot of factors.

In short, when I write C# app what of the above examples is preferred?

Update

If the answer is not, why its different from this:

foreach (var x in MyMethod.GetEnumeration())

here there no need to do:

var lst = MyMethod.GetEnumeration();
foreach (var x in lst)
Was it helpful?

Solution

In the general case, no. Because: side-effects. In general, any.Method(args) can do something different every time (logging, randomness, incrementing counters, connecting to an external unmanaged resource, etc), and must be called each time to retain the original semantic. It could be that a white-list of "pure" functions is maintained, but I can think of no special reason to include int.Parse in that.

Basically, if you want to hoist it: hoist it yourself. The code in your second example is reasonable (personally I'd add an else, i.e else if).


Additionally: your example calls SomeStringProperty multiple times : that too must be called multiple times to retain the semantic, and could behave differently.

Finally, in a multi-threaded world, the field itself could have changed.

OTHER TIPS

Re the update: that example is completely unrelated. You might as well give an example of:

var val = MyMethod.SomeMethod();

and compare it to:

var tmp = MyMethod.SomeMethod();
var val = tmp;

in both cases, all you've done is separate the invoke/evaluation from the usage by way of assignment into an intermediary variable. And, in both cases, if we assume that the lst / tmp variable isn't used anywhere else, we can be reasonably sure that the compiler (not the JIT) actually removes that variable anyway - so the two are not just logically equivalent - they are actually equivalent. In this scenario, we haven't removed any method calls etc - we only evaluate it once. Completely unrelated scenario.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top