1

I have a loop like

for (int i = 2; i <= ViewBag.numPages; ++i)

and I'm wondering if it'll be faster if I write it as

for (int i = 2, n = ViewBag.numPages; i <= n; ++i)

Please give me a deep (low-level) explanation if possible

Donald Knuth
  • 145
  • 4
  • 3
    possible duplicate of https://stackoverflow.com/questions/262934/is-it-costly-to-do-array-length-or-list-count-in-a-loop or https://stackoverflow.com/questions/1124753/performance-difference-for-control-structures-for-and-foreach-in-c-sharp – nozzleman Oct 14 '15 at 06:16
  • 1
    If it does, the compiler will optimize it anyway, unless you turn that off. Even then, the cost is likely to be very small, like two machine instructions. – Paul Kienitz Oct 14 '15 at 06:18
  • 2
    Also: recommended reading: http://www.codeproject.com/Articles/844781/Digging-Into-NET-Loop-Performance-Bounds-checking – nozzleman Oct 14 '15 at 06:21
  • @PaulKienitz: It could be costly. Although not in C#, in C you could have a structure allocated in RAM. Accessing that repeatedly (using `->` notation) would be extremely costly as RAM access would take far longer than register memory. – Dair Oct 14 '15 at 06:21
  • 1
    You have an odd definition of ”extremely”. First of all, re-hitting the same address would be cached. Second, ram access cost wouldn't be extreme until your loop counts were starting to worry about overflowing an int32. – Paul Kienitz Oct 14 '15 at 06:23
  • @PaulKienitz: Ok, maybe "extremely" is a bit of an exaggeration, but it could add up, especially if the loop has loops within loops. – Dair Oct 14 '15 at 06:26
  • this might help http://stackoverflow.com/a/262955/4635947 – Aditya Korti Oct 14 '15 at 06:40
  • 3
    By the way. You are not Donald Knuth.. shame on you to misuse the name and ask such a simple question that the real person would know for sure! – Niki van Stein Oct 14 '15 at 06:45
  • 1
    @BasvanStein agreed. Downvoted just for that reason. – jeroenh Oct 14 '15 at 06:48
  • @BasvanStein Anyone who knows who Donald Knuth is will obviously understand that OP is not Donald Knuth. – Rotem Oct 14 '15 at 06:49
  • 1
    @Rotem, agreed, but I just don't like fakers. – Niki van Stein Oct 14 '15 at 06:50
  • 1
    @Rotem still, distasteful practice IMO – jeroenh Oct 14 '15 at 06:50

2 Answers2

1

Does the dot operator cost anything in terms of operations?

It depends. For your ASP.NET code:

for (int i = 2; i <= ViewBag.numPages; ++i)

...then the above may be subject to optimisations (or perhaps CPU caching) so anything you do in an attempt to optimise may not be noticeable.

COM

However, your question title does not mention ASP.NET (though it is later tagged ) so imagine if ViewBag was actually a COM object.

for (int i = 2; i <= ViewBag.numPages; ++i)

...then that would be very expensive and not subject to .NET optimisation I would not think. Invoking COM, particularly via IDispatch is significantly slower than accessing a .NET property on a local object.

So in the case of COM you should:

for (int i = 2, n = ViewBag.numPages; i <= n; ++i)
  • How could the CPU cache the value without asserting that no other thread is changing `ViewBag.numPages` during the loop? – Rotem Oct 14 '15 at 06:36
  • Asp.net It is in the tags though.. – Niki van Stein Oct 14 '15 at 06:37
  • @BasvanStein Agreed. I don't believe the question to be significantly tied to ASP.NET though. :) –  Oct 14 '15 at 06:41
  • 2
    @Rotem Simple - you have few guarantees about staleness of data in multi-threading. It's one of the things that makes multi-threading rather hard. The CPU will track changes to the memory location and flush the relevant cache lines if necessary, just as with single-threaded code - however, it doesn't happen immediately. – Luaan Oct 14 '15 at 06:41
1

Assuming that ViewBag.numPages stays constant for the duration of your loop, I would favor the second variant, i.e.:

for (int i = 2, n = ViewBag.numPages; i <= n; ++i)

Why?

  • Perhaps your first numPages is a simple field, but if it is a non-trivial property, your loop has to evaluate it (call its getter) before each iteration, which is certainly costlier than evaluating it once and then caching the result.

  • Compiler optimizations are an implementation detail of the compiler, you do not know what exactly the compiler does for you to improve performance.

    Caching ViewBag.numPages manually means that you won't have to rely on an optimization that the compiler may or may not do for you.

That being said, if ViewBag.numPages is a (constant) field, not a property, then both code variants are likely so close in execution speed (in the best case, we're talking about the difference between accessing a CPU register vs. accessing atomically one memory location that might be in the CPU memory cache) that the difference doesn't matter at all.

Community
  • 1
  • 1
stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268