diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2022-05-18 21:20:37 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-18 21:20:37 +0200 |
commit | f1f299527634a425cb34b621d6201fa9172d3529 (patch) | |
tree | 7cb80b97b27aa56c830986c533b9f5bb255264b3 /psutil/tests | |
parent | 33981759a67601b91d925a14403077e8d218c015 (diff) | |
download | psutil-f1f299527634a425cb34b621d6201fa9172d3529.tar.gz |
[Linux] Speedup `Process.full_memory_info()` (#2108)
`Process.memory_full_info()` (reporting proecss USS/PSS/Swap memory) now reads ``/proc/pid/smaps_rollup`` instead of ``/proc/pids/smaps`` which makes it 5 times faster.
Without patch:
```
~/svn/psutil {linux-smaps-rollup}$ python3 -m timeit -s "import psutil; p = psutil.Process()" "p.memory_full_info()"
500 loops, best of 5: 518 usec per loop
```
With patch (5 times faster):
```
~/svn/psutil {linux-smaps-rollup}$ python3 -m timeit -s "import psutil; p = psutil.Process()" "p.memory_full_info()"
2000 loops, best of 5: 111 usec per loop
```
----
`make test-memleaks` suite, who heavily rely on `Process.memory_full_info()`, also received a nice speedup:
Before patch:
```
$ make test-memleaks
----------------------------------------------------------------------
Ran 99 tests in 1.646s
OK (skipped=9)
SUCCESS
```
After patch:
```
$ make test-memleaks
----------------------------------------------------------------------
Ran 99 tests in 1.195s
OK (skipped=9)
SUCCESS
```
Diffstat (limited to 'psutil/tests')
-rwxr-xr-x | psutil/tests/test_linux.py | 35 |
1 files changed, 13 insertions, 22 deletions
diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py index 8dd4caae..51e8be51 100755 --- a/psutil/tests/test_linux.py +++ b/psutil/tests/test_linux.py @@ -1775,28 +1775,19 @@ class TestSensorsFans(PsutilTestCase): class TestProcess(PsutilTestCase): @retry_on_failure() - def test_memory_full_info(self): - testfn = self.get_testfn() - src = textwrap.dedent(""" - import time - with open("%s", "w") as f: - time.sleep(10) - """ % testfn) - sproc = self.pyrun(src) - call_until(lambda: os.listdir('.'), "'%s' not in ret" % testfn) - p = psutil.Process(sproc.pid) - time.sleep(.1) - mem = p.memory_full_info() - maps = p.memory_maps(grouped=False) + def test_parse_smaps_vs_memory_maps(self): + sproc = self.spawn_testproc() + uss, pss, swap = psutil._pslinux.Process(sproc.pid)._parse_smaps() + maps = psutil.Process(sproc.pid).memory_maps(grouped=False) self.assertAlmostEqual( - mem.uss, sum([x.private_dirty + x.private_clean for x in maps]), + uss, sum([x.private_dirty + x.private_clean for x in maps]), delta=4096) self.assertAlmostEqual( - mem.pss, sum([x.pss for x in maps]), delta=4096) + pss, sum([x.pss for x in maps]), delta=4096) self.assertAlmostEqual( - mem.swap, sum([x.swap for x in maps]), delta=4096) + swap, sum([x.swap for x in maps]), delta=4096) - def test_memory_full_info_mocked(self): + def test_parse_smaps_mocked(self): # See: https://github.com/giampaolo/psutil/issues/1222 with mock_open_content( "/proc/%s/smaps" % os.getpid(), @@ -1823,12 +1814,12 @@ class TestProcess(PsutilTestCase): Locked: 19 kB VmFlags: rd ex """).encode()) as m: - p = psutil.Process() - mem = p.memory_full_info() + p = psutil._pslinux.Process(os.getpid()) + uss, pss, swap = p._parse_smaps() assert m.called - self.assertEqual(mem.uss, (6 + 7 + 14) * 1024) - self.assertEqual(mem.pss, 3 * 1024) - self.assertEqual(mem.swap, 15 * 1024) + self.assertEqual(uss, (6 + 7 + 14) * 1024) + self.assertEqual(pss, 3 * 1024) + self.assertEqual(swap, 15 * 1024) # On PYPY file descriptors are not closed fast enough. @unittest.skipIf(PYPY, "unreliable on PYPY") |