Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" C Function Profiler Using Google Perftools
Note that the profiler samples 100x per second by default. In particular, you cannot profile anything shorter than 10ms. You can adjust the rate with the ``CPUPROFILE_FREQUENCY`` environment variable if you want to change it.
EXAMPLES::
sage: from sage.misc.gperftools import Profiler, run_100ms sage: prof = Profiler() sage: prof.start() # optional - gperftools sage: run_100ms() sage: prof.stop() # optional - gperftools PROFILE: interrupts/evictions/bytes = ...
REFERENCE:
Uses the `Google performance analysis tools <https://github.com/gperftools/gperftools>`_. Note that they are not included in Sage, you have to install them yourself on your system.
AUTHORS:
- Volker Braun (2014-03-31): initial version """
#***************************************************************************** # Copyright (C) 2014 Volker Braun <vbraun.name@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # # http://www.gnu.org/licenses/ #*****************************************************************************
""" Interface to the gperftools profiler
INPUT:
- ``filename`` -- string or ``None`` (default). The file name to log to. By default, a new temporary file is created.
EXAMPLES::
sage: from sage.misc.gperftools import Profiler sage: Profiler() Profiler logging to ... """ else: self._filename = filename
""" Return the file name
OUTPUT:
String.
EXAMPLES::
sage: from sage.misc.gperftools import Profiler sage: prof = Profiler() sage: prof.filename() '.../tmp_....perf' """
""" Return string representation
OUTPUT:
String.
EXAMPLES::
sage: from sage.misc.gperftools import Profiler sage: Profiler() Profiler logging to .../tmp....perf """
""" Return libc
OUTPUT:
A ctypes shared library handle.
EXAMPLES::
sage: from sage.misc.gperftools import Profiler sage: Profiler()._libc() <CDLL '...', handle ... at ...> """ global libc return libc else: raise ImportError('failed to open libc')
""" Return libprofiler
OUTPUT:
A ctypes shared library handle.
EXAMPLES::
sage: from sage.misc.gperftools import Profiler sage: Profiler()._libprofiler() # optional - gperftools <CDLL 'libprofiler...', handle ... at ...> """ global libprofiler if libprofiler is not None: return libprofiler import ctypes, ctypes.util name = ctypes.util.find_library('profiler') if name: libprofiler = ctypes.CDLL(name) return libprofiler else: raise ImportError('failed to open libprofiler, make sure gperftools is installed')
""" Start profiling
EXAMPLES::
sage: from sage.misc.gperftools import Profiler, run_100ms sage: prof = Profiler() sage: prof.start() # optional - gperftools sage: run_100ms() sage: prof.stop() # optional - gperftools PROFILE: interrupts/evictions/bytes = ... """ from signal import SIGPROF, SIG_DFL self._previous_sigprof_handler = self._libc().signal(SIGPROF, SIG_DFL) profiler = self._libprofiler() self._t_start = time.time() rc = profiler.ProfilerStart(self.filename()) if rc < 0: raise ValueError('profiler failed to start')
""" Stop the CPU profiler
EXAMPLES::
sage: from sage.misc.gperftools import Profiler, run_100ms sage: prof = Profiler() sage: prof.start() # optional - gperftools sage: run_100ms() sage: prof.stop() # optional - gperftools PROFILE: interrupts/evictions/bytes = ... """ profiler = self._libprofiler() profiler.ProfilerStop() self._t_stop = time.time() if (self._t_stop - self._t_start) < 0.1: from warnings import warn warn('not enough samples, total runtime was ' 'less than 100ms', RuntimeWarning)
def _pprof(self): """ Return the name of the ``pprof`` binary.
OUTPUT:
String. The name of the gperftools ``pprof`` utility. A ``OSError`` is raised if it cannot be found.
EXAMPLES::
sage: import six sage: from sage.misc.gperftools import Profiler sage: prof = Profiler() sage: try: ....: pp = prof._pprof() ....: assert isinstance(pp, six.string_types) ....: except OSError: ....: pass # not installed """ if 'gperftools' not in version: from warnings import warn warn('the "{0}" utility does not appear to be the gperftools profiler' .format(name), RuntimeWarning) continue return name
""" Return the name of the Sage Python interpreter.
OUTPUT:
String.
EXAMPLES::
sage: from sage.misc.gperftools import Profiler sage: prof = Profiler() sage: prof._executable() '.../python...' """
""" Run the pprof binary
INPUT:
- ``args`` -- list of strings. The arguments to ``pprof``.
- ``kwds`` -- keyword arguments passed to ``subprocess.check_call``.
EXAMPLES::
sage: from sage.misc.gperftools import Profiler sage: prof = Profiler() sage: prof._call_pprof('--help') # optional - gperftools Usage: pprof [options] <program> <profiles> ... """ from subprocess import check_call check_call([self._pprof()] + list(args), **kwds)
""" Print text report
OUTPUT:
Nothing. A textual report is printed to stdout.
EXAMPLES::
sage: from sage.misc.gperftools import Profiler sage: prof = Profiler() sage: prof.start() # optional - gperftools sage: # do something sage: prof.stop() # optional - gperftools PROFILE: interrupts/evictions/bytes = ... sage: prof.top() # optional - gperftools Using local file ... Using local file ... """ args = [] if cumulative: args += ['--cum'] args += ['--text', self._executable(), self.filename()] self._call_pprof(*args)
""" Save report to disk.
INPUT:
- ``filename`` -- string. The filename to save at. Must end with one of ``.dot``, ``.ps``, ``.pdf``, ``.svg``, ``.gif``, or ``.txt`` to specify the output file format.
- ``cumulative`` -- boolean (optional, default: ``True``). Whether to return cumulative timings.
- ``verbose`` -- boolean (optional, default: ``True``). Whether to print informational messages.
EXAMPLES::
sage: from sage.misc.gperftools import Profiler, run_100ms sage: prof = Profiler() sage: prof.start() # optional - gperftools sage: run_100ms() # optional - gperftools sage: prof.stop() # optional - gperftools PROFILE: interrupts/evictions/bytes = ... sage: f = tmp_filename(ext='.txt') # optional - gperftools sage: prof.save(f, verbose=False) # optional - gperftools """ args = [] if cumulative: args += ['--cum'] if filename.endswith('.dot'): args += ['--dot'] elif filename.endswith('.ps'): args += ['--ps'] elif filename.endswith('.pdf'): args += ['--pdf'] elif filename.endswith('.svg'): args += ['--svg'] elif filename.endswith('.txt'): args += ['--text'] elif filename.endswith('.gif'): args += ['--gif'] else: raise ValueError('unknown extension') args += [self._executable(), self.filename()] stderr = sys.stdout if verbose else False with open(filename, 'wb') as outfile: self._call_pprof(*args, stdout=outfile, stderr=stderr)
""" Profile single statement.
- ``s`` -- string. Sage code to profile.
- ``evaluator`` -- callable to evaluate.
EXAMPLES::
sage: import sage.misc.gperftools as gperf sage: ev = lambda ex:eval(ex, globals(), locals()) sage: gperf.crun('gperf.run_100ms()', evaluator=ev) # optional - gperftools PROFILE: interrupts/evictions/bytes = ... Using local file ... Using local file ... """ prof = Profiler() from sage.repl.preparse import preparse py_s = preparse(s) prof.start() try: evaluator(py_s) finally: prof.stop() prof.top()
""" Used for doctesting.
A function that performs some computation for more than (but not that much more than) 100ms.
EXAMPLES::
sage: from sage.misc.gperftools import run_100ms sage: run_100ms() """
|