GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — gh-146558: optimize dict access with objects with known hash by kumaraditya303 · Pull Request #146559 · python/cpython Conversation
|
| Benchmark | No JIT | JIT | Speedup |
|---|---|---|---|
| dict_get[str] | 55.7M/s | 70.1M/s | +26% |
| dict_get[int] | 55.5M/s | 75.4M/s | +36% |
| dict_get[float] | 50.9M/s | 74.7M/s | +47% |
| dict_get[complex] | 44.9M/s | 74.9M/s | +67% |
| dict_store[str] | 74.9M/s | 85.7M/s | +14% |
| dict_store[int] | 76.0M/s | 94.1M/s | +24% |
| dict_store[float] | 66.6M/s | 97.0M/s | +46% |
| dict_store[complex] | 55.9M/s | 98.0M/s | +75% |
| dict_get[multi] | 23.4M/s | 35.1M/s | +50% |
| dict_get[obj] | 52.9M/s | 68.8M/s | +30% |
| dict_store[obj] | 75.4M/s | 92.5M/s | +23% |
"""Benchmark dict get/store with constant keys to measure _BINARY_OP_SUBSCR_DICT_KNOWN_HASH and _STORE_SUBSCR_DICT_KNOWN_HASH speedup. Usage: PYTHON_JIT=0 ./python.exe bench_dict_known_hash.py PYTHON_JIT=1 ./python.exe bench_dict_known_hash.py """ import time import os import sys N = 50_000_000 def bench_get_str(n): d = {'a': 1, 'b': 2, 'c': 3} x = 0 for _ in range(n): x += d['a'] return x def bench_get_int(n): d = {1: 10, 2: 20, 3: 30} x = 0 for _ in range(n): x += d[1] return x def bench_store_str(n): d = {} for _ in range(n): d['a'] = 1 return d def bench_store_int(n): d = {} for _ in range(n): d[1] = 1 return d def bench_get_float(n): d = {1.5: 1, 2.5: 2, 3.5: 3} x = 0 for _ in range(n): x += d[1.5] return x def bench_store_float(n): d = {} for _ in range(n): d[1.5] = 1 return d def bench_get_complex(n): d = {1+2j: 1, 3+4j: 2} x = 0 for _ in range(n): x += d[1+2j] return x def bench_store_complex(n): d = {} for _ in range(n): d[1+2j] = 1 return d def bench_get_multi(n): d = {'a': 1, 1: 2, b'x': 3, (1, 2): 4} x = 0 for _ in range(n): x += d['a'] + d[1] + d[b'x'] + d[(1, 2)] return x class _Key: pass _KEY = _Key() def bench_get_obj(n): d = {_KEY: 1} x = 0 for _ in range(n): x += d[_KEY] return x def bench_store_obj(n): d = {} for _ in range(n): d[_KEY] = 1 return d def run_avg(name, func, n, runs=3): func(1000) # warmup times = [] for _ in range(runs): t0 = time.perf_counter() func(n) times.append(time.perf_counter() - t0) avg = sum(times) / len(times) rate = n / avg / 1e6 print(f" {name:25s} {avg:.3f}s ({rate:.1f}M iter/s)") return avg if __name__ == "__main__": jit = "JIT" if os.environ.get("PYTHON_JIT", "1") == "1" else "no JIT" print(f"Python {sys.version.split()[0]} ({jit}), avg of 3 runs\n") run_avg("dict_get[str]", bench_get_str, N) run_avg("dict_get[int]", bench_get_int, N) run_avg("dict_get[float]", bench_get_float, N) run_avg("dict_get[complex]", bench_get_complex, N) run_avg("dict_store[str]", bench_store_str, N) run_avg("dict_store[int]", bench_store_int, N) run_avg("dict_store[float]", bench_store_float, N) run_avg("dict_store[complex]",bench_store_complex,N) run_avg("dict_get[multi]", bench_get_multi, N // 4) run_avg("dict_get[obj]", bench_get_obj, N) run_avg("dict_store[obj]", bench_store_obj, N)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
…ktor * upstream/main: (119 commits) pythongh-144270: Make SubElement parent and tag positional-only (pythonGH-144845) pythongh-146558: JIT optimize dict access for objects with known hash (python#146559) pythongh-139922: always run MSVC 64-bit tail-calling CI (pythonGH-146570) pythongh-126835: Fix _PY_IS_SMALL_INT() macro (python#146631) pythongh-146587: fix type slot assignment incase of multiple slots for same name (python#146593) pythongh-138122: Add differential flame graph (python#145785) pythongh-146416: Emscripten: Improve standard stream handling in node_entry.mjs (python#146417) pythongh-146444: Don't package as part of iOS 'build hosts' target (python#146628) pythongh-138850: Add --disable-epoll to configure (pythonGH-145768) pythongh-146444: Make Platforms/Apple/ compatible with Python 3.9 (python#146624) pythongh-138577: Fix keyboard shortcuts in getpass with echo_char (python#141597) pythongh-146556: Fix infinite loop in annotationlib.get_annotations() on circular __wrapped__ (python#146557) pythongh-146579: _zstd: Fix decompression options dict error message (python#146577) pythongh-146083: Upgrade bundled Expat to 2.7.5 (python#146085) pythongh-146080: fix a crash in SNI callbacks when the SSL object is gone (python#146573) pythongh-146090: fix memory management of internal `sqlite3` callback contexts (python#146569) pythongh-145876: Do not mask KeyErrors raised during dictionary unpacking in call (pythonGH-146472) pythongh-146004: fix test_args_from_interpreter_flags on windows (python#146580) pythongh-139003: Use frozenset for module level attributes in _pyrepl.utils (python#139004) pythonGH-146527: Add more data to GC statistics and add it to PyDebugOffsets (python#146532) ...
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.