Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add guppy backend #256

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions memory_profiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@
else:
from signal import SIGKILL
import psutil
import dis


try:
from guppy import hpy
guppy_installed = True
_hpy = hpy()
except ImportError:
guppy_installed = False


# TODO: provide alternative when multiprocessing is not available
Expand Down Expand Up @@ -179,6 +188,13 @@ def posix_tool():
else:
return -1

def guppy_memory():
size = _hpy.heap().size / (1024 * 1024)
if timestamps:
return size, time.time()
else:
return size

if backend == 'tracemalloc' and \
(filename is None or filename == '<unknown>'):
raise RuntimeError(
Expand All @@ -187,7 +203,9 @@ def posix_tool():

tools = {'tracemalloc': tracemalloc_tool,
'psutil': ps_util_tool,
'posix': posix_tool}
'posix': posix_tool,
'guppy': guppy_memory,
}
return tools[backend]()


Expand Down Expand Up @@ -736,10 +754,16 @@ def trace_memory_usage(self, frame, event, arg):
self.prevlines.append(frame.f_lineno)
elif event == 'line':
# trace needs current line and previous line
self.code_map.trace(frame.f_code, self.prevlines[-1], self.prev_lineno)
# saving previous line
self.prev_lineno = self.prevlines[-1]
self.prevlines[-1] = frame.f_lineno
_run = True
if self.backend == 'guppy':
if self.prevlines[-1] == self.prev_lineno:
# the reason for this is because for code like [i for i in range(0, 1000000)] guppy will be extremely slow
_run = False
Copy link
Author

@dxe4 dxe4 Nov 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can cause issues if you want to measure the memory of a side effect eg

[foo() for i in range(0, 500)]
def foo():
     make_big_array = [i for i in random.randint(0, int(1e9))]

i haven't tested it.
although it will give correct results for this case #236 (comment)

if _run:
self.code_map.trace(frame.f_code, self.prevlines[-1], self.prev_lineno)
# saving previous line
self.prev_lineno = self.prevlines[-1]
self.prevlines[-1] = frame.f_lineno
elif event == 'return':
lineno = self.prevlines.pop()
self.code_map.trace(frame.f_code, lineno, self.prev_lineno)
Expand Down Expand Up @@ -1134,6 +1158,7 @@ def choose_backend(new_backend=None):
('psutil', True),
('posix', os.name == 'posix'),
('tracemalloc', has_tracemalloc),
('guppy', guppy_installed),
]
backends_indices = dict((b[0], i) for i, b in enumerate(all_backends))

Expand Down Expand Up @@ -1249,7 +1274,7 @@ def flush(self):
help='''print timestamp instead of memory measurement for
decorated functions''')
parser.add_argument('--backend', dest='backend', type=str, action='store',
choices=['tracemalloc', 'psutil', 'posix'], default='psutil',
choices=['tracemalloc', 'psutil', 'posix', 'guppy'], default='psutil',
help='backend using for getting memory info '
'(one of the {tracemalloc, psutil, posix})')
parser.add_argument("program", nargs=REMAINDER,
Expand Down