Skip to content

Commit 4742692

Browse files
author
Giuseppe Lumia
committed
Simplify sampler's logic
As storers always expect a binary file to read from, we can simplify samplers by delegating to the profiler the creation of the in-memory file and the interaction with the storer.
1 parent 21f9f7e commit 4742692

File tree

4 files changed

+24
-18
lines changed

4 files changed

+24
-18
lines changed

benchmark/record_frames.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"""
77

88
import pickle
9-
from io import BytesIO
109

1110
from handler import handler
1211

@@ -50,11 +49,8 @@ def sample(self, frame):
5049
# Record custom stack
5150
self.data.append(frames[-1])
5251

53-
def dump(self, storer):
54-
file = BytesIO()
52+
def dump(self, file):
5553
pickle.dump(self.data, file)
56-
file.seek(0)
57-
storer.store(file)
5854

5955

6056
if __name__ == "__main__":

pylaprof/__init__.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,12 @@ def sample(self, frame):
107107
"""
108108
pass # pragma: no cover
109109

110-
def dump(self, storer):
110+
def dump(self, file):
111111
"""
112112
Dump sampling data.
113113
114-
storer (Storer)
115-
Storer to use for data's storage.
114+
file
115+
A file-like object in binary mode where to write data.
116116
"""
117117
pass # pragma: no cover
118118

@@ -136,13 +136,10 @@ def sample(self, frame):
136136
frame = frame.f_back
137137
self._data[tuple(stack)] += 1
138138

139-
def dump(self, storer):
140-
file = BytesIO()
139+
def dump(self, file):
141140
for stack, hits in self._data.items():
142141
line = f"{';'.join(stack[::-1])} {hits}\n"
143142
file.write(line.encode())
144-
file.seek(0)
145-
storer.store(file)
146143

147144

148145
class Profiler(threading.Thread):
@@ -241,7 +238,10 @@ def run(self):
241238
end = time.time()
242239

243240
if end - start >= self.min_time:
244-
self.sampler.dump(self.storer)
241+
file = BytesIO()
242+
self.sampler.dump(file)
243+
file.seek(0)
244+
self.storer.store(file)
245245

246246
stop_event.clear()
247247
self.clean_exit = True

tests/test_profiler.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import sys
22
import threading
33
from inspect import signature
4+
from io import BytesIO
45
from unittest.mock import MagicMock, Mock
56

67
from pylaprof import Profiler, profile
@@ -116,6 +117,8 @@ def test_profiler_run(monkeypatch):
116117
profiler = Profiler(period=period, sampler=Mock(), storer=Mock())
117118
profiler._test = Mock(side_effect=lambda ident: ident == ident1)
118119
profiler._stop_event = Mock()
120+
report = b"I'm supposed to be a profiling report"
121+
profiler.sampler.dump.side_effect = lambda file: file.write(report)
119122

120123
profiler.start()
121124
profiler.stop()
@@ -126,6 +129,13 @@ def test_profiler_run(monkeypatch):
126129
sampler_calls = {args for args, _ in profiler.sampler.sample.call_args_list}
127130
assert (frame1,) in sampler_calls
128131
assert (frame2,) not in sampler_calls
132+
profiler.sampler.dump.assert_called()
133+
profiler.storer.store.assert_called_once()
134+
store_args = profiler.storer.store.call_args_list[0][0]
135+
file = store_args[0]
136+
assert isinstance(file, BytesIO)
137+
file.seek(0)
138+
assert file.read() == report
129139
profiler._stop_event.wait.assert_called_with(period)
130140
profiler._stop_event.clear.assert_called()
131141
assert profiler.clean_exit is True

tests/test_sampler.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from collections import defaultdict
2+
from io import BytesIO
23
from unittest.mock import Mock
34

45
from pylaprof import StackCollapse
@@ -85,10 +86,9 @@ def test_stack_collapse_dump():
8586
"three (some_path/some_module.py:42);one (some_path/some_module.py:12) 4\n"
8687
+ "three_v2 (some_path/some_module.py:82);some_func (some_path/some_other_module.py:11) 2\n" # noqa
8788
).encode()
88-
storer = Mock()
89+
file = BytesIO()
8990

90-
stack_collapse.dump(storer=storer)
91+
stack_collapse.dump(file=file)
9192

92-
storer.store.assert_called()
93-
args, _ = storer.store.call_args_list[0]
94-
assert args[0].read() == exp_file
93+
file.seek(0)
94+
assert file.read() == exp_file

0 commit comments

Comments
 (0)