我正在尝试使用 Python 进行实验,试图找出它可以在一分钟内将整数加一多少次。假设两台计算机除了 CPU 的速度之外是相同的,这应该可以估计某些 CPU 操作对于相关计算机可能需要多快。
下面的代码是为满足上述要求而设计的测试示例。这个版本比第一次尝试快 20%,比第三次尝试快 150%。任何人都可以就如何在一分钟内获得最多的添加提出任何建议吗?更高的数字是可取的。
编辑 1:这个实验是用 Python 3.1 编写的,比第四次加速尝试快 15%。
def start(seconds):
import time, _thread
def stop(seconds, signal):
time.sleep(seconds)
signal.pop()
total, signal = 0, [None]
_thread.start_new_thread(stop, (seconds, signal))
while signal:
total += 1
return total
if __name__ == '__main__':
print('Testing the CPU speed ...')
print('Relative speed:', start(60))
编辑 2: 关于在 while 循环中使用 True
而不是 1
:应该没有速度差异。下面的实验证明它们是一样的。首先,创建一个名为 main.py
的文件并将以下代码复制到其中。
def test1():
total = 0
while 1:
total += 1
def test2():
total = 0
while True:
total += 1
if __name__ == '__main__':
import dis, main
dis.dis(main)
运行代码应该会产生以下输出,显示代码的实际编译方式以及生成的 Python 虚拟机指令 结果是什么。
Disassembly of test1:
2 0 LOAD_CONST 1 (0)
3 STORE_FAST 0 (total)
3 6 SETUP_LOOP 13 (to 22)
4 >> 9 LOAD_FAST 0 (total)
12 LOAD_CONST 2 (1)
15 INPLACE_ADD
16 STORE_FAST 0 (total)
19 JUMP_ABSOLUTE 9
>> 22 LOAD_CONST 0 (None)
25 RETURN_VALUE
Disassembly of test2:
7 0 LOAD_CONST 1 (0)
3 STORE_FAST 0 (total)
8 6 SETUP_LOOP 13 (to 22)
9 >> 9 LOAD_FAST 0 (total)
12 LOAD_CONST 2 (1)
15 INPLACE_ADD
16 STORE_FAST 0 (total)
19 JUMP_ABSOLUTE 9
>> 22 LOAD_CONST 0 (None)
25 RETURN_VALUE
发出的 PVMI(字节码)完全相同,因此两个循环的运行速度应该没有任何差异。
最佳答案
我看到与 the @Amber's one 几乎相同但始终更好 (~2%) 的结果在 my machine在 Python 3.1.2 上的代码:
import signal
class Alarm(Exception):
pass
def alarm_handler(signum, frame):
raise Alarm
def jfs_signal(seconds):
# set signal handler
signal.signal(signal.SIGALRM, alarm_handler)
# raise Alarm in `seconds` seconds
signal.alarm(seconds)
total = 0
try:
while 1:
total += 1
finally:
signal.alarm(0) # disable the alarm
return total
这是使用 subprocess
模块运行可中断循环的变体:
#!/usr/bin/env python
# save it as `skytower.py` file
import atexit
import os
import signal
import subprocess
import sys
import tempfile
import time
def loop():
@atexit.register
def print_total():
print(total)
total = 0
while 1:
total += 1
def jfs_subprocess(seconds):
# start process, redirect stdout/stderr
f = tempfile.TemporaryFile()
p = subprocess.Popen([sys.executable, "-c",
"from skytower import loop; loop()"],
stdout=f, stderr=open(os.devnull, 'wb'))
# wait
time.sleep(seconds)
# raise KeyboardInterrupt
#NOTE: if it doesn't kill the process then `p.wait()` blocks forever
p.send_signal(signal.SIGINT)
p.wait() # wait for the process to terminate otherwise the output
# might be garbled
# return saved output
f.seek(0) # rewind to the beginning of the file
d = int(f.read())
f.close()
return d
if __name__ == '__main__':
print('total:', jfs_subprocess(60))
它比我机器上的 signal.alarm()
变体慢 ~20%。
关于python - 可以在纯 Python 中加速这个循环吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4676544/