0

Let's say I have a python script script.py and I want to measure the execution time of it just as if I put the whole script in quotation marks and used:

from timeit import Timer
t = Timer(stmt='THE WHOLE SCRIPT')
print(t.timeit())

I could do this by editing script.py, but I'd like not to. What I want is a second script measure.py, which can be executed like ./measure.py script.py, which will basically do the above with any script as an argument.

How could I approach writing such a script measure.py?

user9115052
  • 115
  • 1
  • 8
  • why not import script.py into measure.py and you can call and time the function(s) you want? – Chris_Rands Dec 18 '17 at 23:36
  • I've pointed to that thread repeatedly, but you don't seem to be trying out different methods mentioned there. Have you tried https://stackoverflow.com/a/45227180/650884? – Pavel Dec 18 '17 at 23:41
  • Does `Timer(stmt=open('script.py').read())` not work? – Stefan Pochmann Dec 19 '17 at 00:04
  • @Chris_Rands Because often the script is really simple and does not contain functions only. – user9115052 Dec 19 '17 at 00:12
  • @Pavel I did saw your original comment to the second answer on that post and it was interesting, but didn't solve my problem, since I didn't want to edit the script and neither had a specific function to call. The answer you linked now is really interesting. The only thing I need to think about a bit more is handling the printing by the script (it'll spam the console, if timeit is called repeatedly). – user9115052 Dec 19 '17 at 00:16
  • @StefanPochmann This works really well thank you! Would you like to post this as an answer? – user9115052 Dec 19 '17 at 00:18
  • @user9115052 Meh... too obvious :-P. Feel free to post it as an answer yourself. Then you could also describe how well it works for you. I don't know that. Better use `with open(...) as ...`, though. – Stefan Pochmann Dec 19 '17 at 00:59

1 Answers1

0

If you also need to pass some arguments to your measure.py script, you could use something like that:

import sys
from timeit import Timer

NUMBER_OF_LOOPS = 10


def main():
    if len(sys.argv) > 1:
        command = [sys.executable] + sys.argv[1:]
        print(' '.join(command))
        timer = Timer(
            stmt=f'subprocess.run({command})',
            setup='import subprocess',
        )

        timing = timer.timeit(number=NUMBER_OF_LOOPS)/NUMBER_OF_LOOPS
        print(f'Mean execution time: {timing} s')
    else:
        print('You must provide a Python script path as argument.')


if __name__ == '__main__':
    main()

The above can be called using: python measure.py script.py -argument1 value ...

Note that using open('script.py, 'r').read() is correct and will close the file after reading it, since you do not assign it to a variable. The proposed solution (by @Stefan Pochmann) was:

from timeit import Timer


t = Timer(stmt=open('script.py', 'r').read(), number=10)
print(t.timeit())