Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the globals argument of timeit.timeit

Tags:

python-3.5

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?

like image 942
Jonathan Avatar asked Jul 03 '17 17:07

Jonathan


People also ask

What does %% Timeit do in Python?

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.

What value does Timeit return?

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.

What unit does Timeit use?

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.


1 Answers

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.

  1. Need to access globals
  2. Need to access locals
  3. Custom namespace

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})
  1. In 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
  2. On the contrary, if you pass 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()
  3. The last one is a general scenario where you need both the local vars in the function and general imports. If you keep in mind that the parameter globals can be specified as a dictionary, you just need to provide the necessary keys, you can customize it.
like image 122
Guiem Bosch Avatar answered Jan 01 '23 09:01

Guiem Bosch