1

On the flip side, timeit runs through the code 1,000,000 times to get a reasonable asymptotic comparison to other code. cProfile only runs through the code once, and with only 3 decimal places in the results (0.000), it is not enough to get the full picture.

You get unuseful results like this:

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.000    0.000 {built-in method builtins.exec}
    1    0.000    0.000    0.000    0.000 <string>:1(<module>)
    1    0.000    0.000    0.000    0.000 a.py:27(function)
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
NoName
  • 9,824
  • 5
  • 32
  • 52
  • 2
    You'd be better using [`line_profiler`](https://github.com/rkern/line_profiler). But, `timeit` is for small snippets, and `cProfile` here is just showing that the particular code you're focusing on is insignificant in relation to the whole program – roganjosh Oct 28 '19 at 19:46
  • You do bring up a good point, it would be impossible to run default `timeit` in a large program. – NoName Oct 28 '19 at 20:06
  • Also, default `timeit` will _not_ run 1mil times through general code. Unless the number of runs is specified, it will dynamically scale the number of runs it actually does. If you're getting a default of 1mil runs on this bit of code, it means it is ridiculously quick. I wouldn't be surprised if it's nothing more than some definitions an no actual calculations running at all. That correlates with your cProfile 0's – roganjosh Oct 28 '19 at 20:08
  • @roganjosh What do you mean dynamically scale? The documentation clearly says the default argument for the `number` of runs parameter is 1mil: `timeit.timeit(stmt='pass', setup='pass', timer=, number=1000000)` https://docs.python.org/2/library/timeit.html – NoName Oct 28 '19 at 20:15
  • Hmm, perhaps you're right. I use the magic `%timeit` and it definitely does scale. Even if the code took 0.01 seconds to run, you'd be waiting for almost 3 hours for that test to finish. I'll have a look to see if the scaling is specifically limited to the magic method – roganjosh Oct 28 '19 at 20:18
  • You're correct: https://ipython.readthedocs.io/en/stable/interactive/magics.html#magic-timeit . "Options: -n: execute the given statement times in a loop. If is not provided, is determined so as to get sufficient accuracy.". Seems I've taken the IPython method for granted – roganjosh Oct 28 '19 at 20:20

1 Answers1

3

Purpose of timeit is to get the throughput of a function, which will always require the code to run multiple times to fade out edge cases and give a good average.

While cProfile, on the other hand, is used to profile each sub-call of the function's stack, to demystify all the magic happening inside a function.

timeit will tell you that there's some optimisation required to function, while cProfile will point you to the right direction telling you which minuscule part of stack is hogging up your turnaround time.

Himanshu Mishra
  • 310
  • 3
  • 13