1

I need to have ten counters that I update in a loop if certain conditions are met.

My normal approach would be to create a list of 10 elements and update the elements of this list.

Dummy example:

my_counters = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
for i in range(100000):
    if condition1:
        my_counters[0] += 1
        my_counters[4] += 1
    elif condition2:
        my_counters[2] += 1
        my_counters[8] += 1
    ...

However this appears to be bad and inefficient code, which I don't really know why.

So I'd like to know what would be the best approach for this simple issue. Of course I have some suggestions:

1) Using one variable for each counter CONS: Too many variables, what if I need 100 counters?

2) Using a numpy array instead of a list (would then it be considered good and efficient code?)

3) Use a dictionary: This way each variable can have a representative name, but wouldn't the hash make the access slower than an index?

What is the correct way of solving this problem?

And also, why is updating elements of a list inneficient? Shouldn't the address be immediate to calculate? Base address + offset

Thanks

  • 2
    Can you give more details on what `condition1` and `condition2` are? – Nils Werner Dec 01 '17 at 15:46
  • It's just a dummy example of a situation inside a loop that will make certain counters be updated. Is the specific case important? –  Dec 01 '17 at 15:47
  • What makes you think that this is what's slowing your code down? – Patrick Haugh Dec 01 '17 at 15:48
  • 1
    Based on what you're giving us, this is probably the best you can do. That said, generally when you're using long chains of 'if... else...' theres something wrong with the larger design. Those long chains of checks are expensive. – sircodesalot Dec 01 '17 at 15:48
  • Actually the number of if...else is not large, what is large in the number of iterations of the loop (several milions), so the update of the counters must be efficient –  Dec 01 '17 at 15:51
  • 1
    you could try just-in-time using pypy. – Jean-François Fabre Dec 01 '17 at 15:53
  • If you are using python 2, you should use xrange(100000). – klaus Dec 01 '17 at 15:56
  • Why do you consider this inefficient code? It's just a linear loop through 100k elements with trivial logic in each iteration accessing a few array indices in a small array per iteration. Should finish in the blink of an eye. I don't use python that much but I'd be surprised if python doesn't do this in milliseconds. Are you doing this a million times in an outer loop? Using dictionary wouldn't help squat unless you can drastically reduce the number of iterations to, say, log_2(100k) or ~17 iterations. It does lend itself well to parallel processing [...] –  Dec 01 '17 at 16:09
  • [...] (just make a copy of the counters in each thread and sum up the values after), but seems overkill to me for such a cheap operation unless you're doing it over and over and over. –  Dec 01 '17 at 16:15

0 Answers0