仅出于实验目的,以下代码的目标以跨平台方式尽可能快地运行,这导致最少的问题,同时允许在Python中停止线程。有问题的特定代码围绕从Thread
继承的threading.Thread
类,它允许通过引发一旦启动后自动被捕获的异常来停止线程。问题很简单:是否可以降低代码报告的W / WO比率而不更改除此处提供的新Thread
类的实现之外的任何内容?
运行时,“有/无线程”比率通常约为5.7(意味着新Thread
类执行基准测试的时间比通常情况下长5.7倍。更改Test.run
的代码可能会导致W / WO比率发生变化,但这不是要应用优化的代码部分,因为它只代表繁忙的无操作循环。目标是更改Thread._bootstrap
的实现,以便解释器必须在虚拟机必须执行的每个字节码指令之间执行的操作开销较少。
#! /usr/bin/env python3
import functools
import statistics
import sys
import threading
import timeit
LIMIT = 1000000
SAMPLES = 30
def main():
repeat = functools.partial(
timeit.repeat,
setup=f'from __main__ import Test; t = Test({LIMIT})',
repeat=SAMPLES,
number=1
)
slow = statistics.mean(repeat('t.start(); t.join()'))
fast = statistics.mean(repeat('t.run()'))
print(f'With thread: {slow:.3f}')
print(f'Without thread: {fast:.3f}')
print(f'W/WO ratio: {slow / fast:.3f}')
class StopThread(StopIteration):
pass
threading.SystemExit = SystemExit, StopThread
class Thread(threading.Thread):
def _bootstrap(self, flag=False):
if threading._trace_hook:
raise RuntimeError('cannot run thread with tracing')
def stop():
nonlocal flag
flag = True
self.stop = stop
def func(*_):
if flag:
raise StopThread()
return func
sys.settrace(func)
super()._bootstrap()
class Test(Thread):
def __init__(self, limit):
super().__init__()
self.limit = limit
def run(self, count=0):
while count < self.limit:
count += 1
if __name__ == '__main__':
main()