Friday, April 29, 2011

Increment/decrement versus assignment?

I'm recording some statistics in my application. One of the statistics is the size of BigDataStructure. I have two options:

  1. Create a counter and increment / decrement the counter each time there is an add/remove from the BigDataStructure.

  2. Each time there is an add/remove from the BigDataStructure, set the counter to BigDataStructure.size().

Is there a good argument for doing it one way or another? Incrementing / decrementing the counter myself avoids a call to BigDataStructure.size(). It also doesn't directly involve the assignment operator (although maybe it does under the hood?)

Given these two options, which one is preferable?

From stackoverflow
  • Incrementing/decrementing are probably faster as it avoids a function call, but there may be a risk of the recorded size versus actual size going out of sync. If you feel confident they wont, then I'd say just use increment/decrementing.

  • .size() would probably be the less error prone of the 2 options because it is idempotent. If you want to get into threading/synchronization issues, .size() is safer here.

    Also, today you have only 1 place that adds entries, and 1 place that removes entries. But maybe in the future that won't be the case.

    JaredPar : +1, for a good word of the day ;)
    John Dibling : +1 if you tell me how to pronounce 'idempotent' :)
    Brian R. Bondy : :) haha, you can hear the pronunciation here: http://dictionary.reference.com/browse/idempotent
  • It depends...

    If BigDataStructure.size() requires work to compute the size, I would use a counter. This would be more efficient in that case.

    If BigDataStructure.size() is something that can be automatically determined by BigDataStructure, so very little computation is required, I'd prefer this approach. It has the advantage of keeping the logic contained in a single place, so it seems much cleaner/more OO in that respect.

  • I'd go with option 1.

    AFAIK, x++ and x += 1 are both the same as x = x + 1 in every way (other than what you type)

    David Thornley : Except, of course, that the later ones can wind up with precedence problems. (x++), (x += 1), and (x = x + 1) are all the same.
    Pukku : @TonyF: Yep, but there's probably an instruction on your iron that does all of these in one cycle, which is not necessarily the case with the call to .size(), right? But still, I suppose that the difference in performance, if any, is not too relevant here.
  • Get the best of both worlds and do them both. You might find something odd going on if your numbers don't agree. That's be a good candidate for asserts.

  • Incrementing and decrementing requires additional care if the adding and deleting is being done from multiple threads. On the other hand, if the size can be calculated quickly, then this has little risk of being out of sync with the correct value.

  • If performance is of concern it depends how expensive the call to size() is. For example a call to size() for a STL list can be O(n). And even if the call is O(1) it may be faster to increment and decrement the external counters. You probably have to do some performance measuring to find out which is more effective. If performance is no concern, then go with the call to size().

  • Why don't you keep the counters internal to BigDataStructure, and then you can increment or decrement whenever you do an add or remove inside those functions. When you call size() you can just return the value of the internal counter.

  • I'd use the first, and then assert(counter == BigDataStructure.size());

0 comments:

Post a Comment