Commit 5db0c940 authored by Brett Cannon's avatar Brett Cannon

Add importlib benchmarks which try to be "realistic" by importing the decimal

module which is the largest module in the stdlib.
parent 3f8ecab5
...@@ -6,6 +6,7 @@ thus has no external changes made to import-related attributes in sys. ...@@ -6,6 +6,7 @@ thus has no external changes made to import-related attributes in sys.
""" """
from . import util from . import util
from .source import util as source_util from .source import util as source_util
import decimal
import imp import imp
import importlib import importlib
import os import os
...@@ -58,7 +59,7 @@ def builtin_mod(seconds, repeat): ...@@ -58,7 +59,7 @@ def builtin_mod(seconds, repeat):
def source_wo_bytecode(seconds, repeat): def source_wo_bytecode(seconds, repeat):
"""Source w/o bytecode""" """Source w/o bytecode: simple"""
sys.dont_write_bytecode = True sys.dont_write_bytecode = True
try: try:
name = '__importlib_test_benchmark__' name = '__importlib_test_benchmark__'
...@@ -72,8 +73,23 @@ def source_wo_bytecode(seconds, repeat): ...@@ -72,8 +73,23 @@ def source_wo_bytecode(seconds, repeat):
sys.dont_write_bytecode = False sys.dont_write_bytecode = False
def decimal_wo_bytecode(seconds, repeat):
"""Source w/o bytecode: decimal"""
name = 'decimal'
decimal_bytecode = imp.cache_from_source(decimal.__file__)
if os.path.exists(decimal_bytecode):
os.unlink(decimal_bytecode)
sys.dont_write_bytecode = True
try:
for result in bench(name, lambda: sys.modules.pop(name), repeat=repeat,
seconds=seconds):
yield result
finally:
sys.dont_write_bytecode = False
def source_writing_bytecode(seconds, repeat): def source_writing_bytecode(seconds, repeat):
"""Source writing bytecode""" """Source writing bytecode: simple"""
assert not sys.dont_write_bytecode assert not sys.dont_write_bytecode
name = '__importlib_test_benchmark__' name = '__importlib_test_benchmark__'
with source_util.create_modules(name) as mapping: with source_util.create_modules(name) as mapping:
...@@ -85,8 +101,19 @@ def source_writing_bytecode(seconds, repeat): ...@@ -85,8 +101,19 @@ def source_writing_bytecode(seconds, repeat):
yield result yield result
def decimal_writing_bytecode(seconds, repeat):
"""Source writing bytecode: decimal"""
assert not sys.dont_write_bytecode
name = 'decimal'
def cleanup():
sys.modules.pop(name)
os.unlink(imp.cache_from_source(decimal.__file__))
for result in bench(name, cleanup, repeat=repeat, seconds=seconds):
yield result
def source_using_bytecode(seconds, repeat): def source_using_bytecode(seconds, repeat):
"""Bytecode w/ source""" """Bytecode w/ source: simple"""
name = '__importlib_test_benchmark__' name = '__importlib_test_benchmark__'
with source_util.create_modules(name) as mapping: with source_util.create_modules(name) as mapping:
py_compile.compile(mapping[name]) py_compile.compile(mapping[name])
...@@ -96,16 +123,32 @@ def source_using_bytecode(seconds, repeat): ...@@ -96,16 +123,32 @@ def source_using_bytecode(seconds, repeat):
yield result yield result
def decimal_using_bytecode(seconds, repeat):
"""Bytecode w/ source: decimal"""
name = 'decimal'
py_compile.compile(decimal.__file__)
for result in bench(name, lambda: sys.modules.pop(name), repeat=repeat,
seconds=seconds):
yield result
def main(import_): def main(import_):
__builtins__.__import__ = import_ __builtins__.__import__ = import_
benchmarks = (from_cache, builtin_mod, source_using_bytecode, benchmarks = (from_cache, builtin_mod,
source_wo_bytecode, source_writing_bytecode,) source_using_bytecode, source_wo_bytecode,
print("Measuring imports/second\n") source_writing_bytecode,
decimal_using_bytecode, decimal_writing_bytecode,
decimal_wo_bytecode,)
seconds = 1
seconds_plural = 's' if seconds > 1 else ''
repeat = 3
header = "Measuring imports/second over {} second{}, best out of {}\n"
print(header.format(seconds, seconds_plural, repeat))
for benchmark in benchmarks: for benchmark in benchmarks:
print(benchmark.__doc__, "[", end=' ') print(benchmark.__doc__, "[", end=' ')
sys.stdout.flush() sys.stdout.flush()
results = [] results = []
for result in benchmark(seconds=1, repeat=3): for result in benchmark(seconds=seconds, repeat=repeat):
results.append(result) results.append(result)
print(result, end=' ') print(result, end=' ')
sys.stdout.flush() sys.stdout.flush()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment