I am attempting to run timeit.timeit in the following class:
from contextlib import suppress
from pathlib import Path
import subprocess
from timeit import timeit
class BackupVolume():
'''
Backup a file system on a volume using tar
'''
targetFile = "bd.tar.gz"
srcPath = Path("/BulkData")
excludes = ["--exclude=VirtualBox VMs/*", # Exclude all the VM stuff
"--exclude=*.tar*"] # Exclude this tar file
@classmethod
def backupData(cls, targetPath="~"): # pylint: disable=invalid-name
'''
Runs tar to backup the data in /BulkData so we can reorganize that
volume. Deletes any old copy of the backup repository.
Parameters:
:param str targetPath: Where the backup should be created.
'''
# pylint: disable=invalid-name
tarFile\
= Path(Path(targetPath /
cls.targetFile).resolve())
with suppress(FileNotFoundError):
tarFile.unlink()
timeit('subprocess.run(["tar", "-cf", tarFile.as_posix(),'
'cls.excludes[0], cls.excludes[1], cls.srcPath.as_posix()])',
number=1, globals=something)
The problem I have is that inside timeit() it cannot interpret subprocess. I believe that the globals argument to timeit() should help but I have no idea how to specify the module namespace. Can someone show me how?
You can use the magic command %%timeit to measure the execution time of the cell. As an example, try executing the same process using NumPy . As with %timeit , -n and -r are optional. Note that %%timeit measures the execution time of the entire cell, so the following example includes the time to import NumPy.
timeit() runs the setup statement one time, then calls the main statement count times. It returns a single floating point value representing the cumulative amount of time spent running the main statement.
The return value is seconds as a float. It is the total time taken to run the test (not counting the setup), so the average time per test is that number divided by the number argument, which defaults to 1 million.
I think in your case globals = globals()
in the timeit
call would work.
Explanation
The globals
argument specifies a namespace in which to execute the code. Due to your import of the subprocess
module (outside the function, even outside the class) you can use globals()
. In doing so you have access to a dictionary of the current module, you can find more info in the documentation.
Super simple example
In this example I'll expose 3 different scenarios.
Code to follow the example:
import subprocess
from timeit import timeit
import math
class ExampleClass():
def performance_glob(self):
return timeit("subprocess.run('ls')", number = 1, globals = globals())
def performance_loc(self):
a = 69
b = 42
return timeit("a * b", number = 1, globals = locals())
def performance_mix(self):
a = 69
return timeit("math.sqrt(a)", number = 1, globals = {'math': math, 'a': a})
performance_glob
you are timing something that needs a global import, the module subprocess
. If you don't pass the globals namespace you'll get an error message like this NameError: name 'subprocess' is not defined
globals()
to the function that depends on local values performance_loc
the needed variables for the timeit execution a
and b
won't be in the scope. That's why you can use locals()
globals
can be specified as a dictionary, you just need to provide the necessary keys, you can customize it.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With