准确测试 Pypy 与 CPython 的性能
Accurately testing Pypy vs CPython performance
问题描述:
我有这个自定义 "checksum" 函数:
NORMALIZER = 0x10000
def get_checksum(part1, part2, salt="trailing"):
"""Returns a checksum of two strings."""
combined_string = part1 + part2 + " " + salt if part2 != "***" else part1
ords = [ord(x) for x in combined_string]
checksum = ords[0] # initial value
# TODO: document the logic behind the checksum calculations
iterator = zip(ords[1:], ords)
checksum += sum(x + 2 * y if counter % 2 else x * y
for counter, (x, y) in enumerate(iterator))
checksum %= NORMALIZER
return checksum
我想在 Python3.6 和 PyPy 性能方面进行测试。我想看看该函数是否会在 PyPy 上执行得更好,但我不完全确定,最可靠和干净的方法是什么。
我的尝试和问题:
目前,我正在为两者使用 timeit
:
$ python3.6 -mtimeit -s "from test import get_checksum" "get_checksum('test1' * 100000, 'test2' * 100000)"
10 loops, best of 3: 329 msec per loop
$ pypy -mtimeit -s "from test import get_checksum" "get_checksum('test1' * 100000, 'test2' * 100000)"
10 loops, best of 3: 104 msec per loop
我担心的是,由于 potential JIT warmup overhead.
,我不确定 timeit
是否适合 PyPy
的工作
此外,PyPy 本身在报告测试结果之前会报告以下内容:
WARNING: timeit is a very unreliable tool. use perf or something else for real measurements
pypy -m pip install perf
pypy -m perf timeit -s 'from test import get_checksum' "get_checksum('test1' * 1000000, 'test2' * 1000000)"
在这些和可能的其他 Python 实现中测试相同的确切功能性能的最佳和最准确的方法是什么?
您可以使用 --repeat
参数增加重复次数,以提高计时精度。见:
不完全清楚您要衡量的是什么。 "Performance" 根据您的用例可能有多种含义。
- 您是否正在尝试在一切都预热后测量函数的原始速度(特别是 JIT,还有库导入、文件加载等...)?那么你可能想要
--repeat
很像 Haroldo_OK 建议的。如果重复次数足够多,花在代码其他部分的时间将逐渐增加 "insignificant".
- 您是为了学习还是为了真实世界的用例而测量事物?如果是后者,最好在类似条件下测试您的代码(您传递给函数的字符串的长度、迭代次数、warm/cold 调用您的代码...)。我的印象是,使用 python interface 而不是 CLI 会给你更多的灵活性来准确地衡量你所追求的。
值得注意的是,timeit
turns off garbage collection,所以如果您正在寻找 "real world" 测量值,也许您想重新打开它(请参阅 link 了解如何操作) .
如果您想提高速度,使用像 cProfile which is supported by both Python3.6 and pypy 这样的分析器可以帮助隔离您要测量其速度的代码吗?
我实际上并没有回答你的问题,但我希望它能有所帮助:)
问题描述:
我有这个自定义 "checksum" 函数:
NORMALIZER = 0x10000
def get_checksum(part1, part2, salt="trailing"):
"""Returns a checksum of two strings."""
combined_string = part1 + part2 + " " + salt if part2 != "***" else part1
ords = [ord(x) for x in combined_string]
checksum = ords[0] # initial value
# TODO: document the logic behind the checksum calculations
iterator = zip(ords[1:], ords)
checksum += sum(x + 2 * y if counter % 2 else x * y
for counter, (x, y) in enumerate(iterator))
checksum %= NORMALIZER
return checksum
我想在 Python3.6 和 PyPy 性能方面进行测试。我想看看该函数是否会在 PyPy 上执行得更好,但我不完全确定,最可靠和干净的方法是什么。
我的尝试和问题:
目前,我正在为两者使用 timeit
:
$ python3.6 -mtimeit -s "from test import get_checksum" "get_checksum('test1' * 100000, 'test2' * 100000)"
10 loops, best of 3: 329 msec per loop
$ pypy -mtimeit -s "from test import get_checksum" "get_checksum('test1' * 100000, 'test2' * 100000)"
10 loops, best of 3: 104 msec per loop
我担心的是,由于 potential JIT warmup overhead.
,我不确定timeit
是否适合 PyPy
的工作
此外,PyPy 本身在报告测试结果之前会报告以下内容:
WARNING: timeit is a very unreliable tool. use perf or something else for real measurements
pypy -m pip install perf
pypy -m perf timeit -s 'from test import get_checksum' "get_checksum('test1' * 1000000, 'test2' * 1000000)"
在这些和可能的其他 Python 实现中测试相同的确切功能性能的最佳和最准确的方法是什么?
您可以使用 --repeat
参数增加重复次数,以提高计时精度。见:
不完全清楚您要衡量的是什么。 "Performance" 根据您的用例可能有多种含义。
- 您是否正在尝试在一切都预热后测量函数的原始速度(特别是 JIT,还有库导入、文件加载等...)?那么你可能想要
--repeat
很像 Haroldo_OK 建议的。如果重复次数足够多,花在代码其他部分的时间将逐渐增加 "insignificant". - 您是为了学习还是为了真实世界的用例而测量事物?如果是后者,最好在类似条件下测试您的代码(您传递给函数的字符串的长度、迭代次数、warm/cold 调用您的代码...)。我的印象是,使用 python interface 而不是 CLI 会给你更多的灵活性来准确地衡量你所追求的。
值得注意的是,timeit
turns off garbage collection,所以如果您正在寻找 "real world" 测量值,也许您想重新打开它(请参阅 link 了解如何操作) .
如果您想提高速度,使用像 cProfile which is supported by both Python3.6 and pypy 这样的分析器可以帮助隔离您要测量其速度的代码吗?
我实际上并没有回答你的问题,但我希望它能有所帮助:)