在测试期间,我发现调用traceback.extract_stack()非常慢。获取堆栈跟踪的价格与执行数据库查询相当。我想知道我是否做错了什么或遗漏了什么。令我惊讶的是,我认为调用extract_stack()是 Python 中的内部调用,它是在运行时在内存中执行的,如果不是即时的,它应该是超快的。相比之下,调用数据库查询涉及到外部服务(网络通信)等。示例代码如下。您可以尝试在 20.000 次迭代中检索回溯所需的时间以及从堆栈跟踪中检索前几项的速度 - 将limit=None参数设置为其他内容。我的测试在各种系统/配置上显示了各种结果,但都有一个共同点,即调用堆栈跟踪并不是便宜几个数量级,它几乎与调用 SQL insert 相同。 20k SQL inserts | 20k stack tracesWin 5.4 sec 14.4 secFreeBSD 5.0 sec 3.7 secUbuntu GCP 16.6 sec 2.4 secWindows:笔记本电脑,本地 SSD。FreeBSD:服务器,本地 SSD。Ubuntu:谷歌云,共享 SSD。我做错了什么或者有什么解释为什么 traceback.extract_stack() 这么慢?我可以以某种方式更快地检索堆栈跟踪吗?示例代码。运行$ pip install pytest然后$ pytest -s -vimport datetimeimport unittestimport tracebackclass TestStackTrace(unittest.TestCase): def test_stack_trace(self): start_time = datetime.datetime.now() iterations = 20000 for i in range(0, iterations): stack_list = traceback.extract_stack(limit=None) # set 0, 1, 2... stack_len = len(stack_list) self.assertEqual(1, 1) finish_time = datetime.datetime.now() print('\nStack length: {}, iterations: {}'.format(stack_len, iterations)) print('Trace elapsed time: {}'.format(finish_time - start_time))您不需要它,但如果您想与 SQL 插入进行比较,就在这里。只需将其作为第二个测试方法插入 TestStackTrace 类即可。运行CREATE DATABASE pytest1;和CREATE TABLE "test_table1" (num_value BIGINT, str_value VARCHAR(10));def test_sql_query(self): start_time = datetime.datetime.now() con_str = "host='127.0.0.1' port=5432 user='postgres' password='postgres' dbname='pytest1'" con = psycopg2.connect(con_str) con.autocommit = True con.set_session(isolation_level='READ COMMITTED') cur = con.cursor() for i in range(0, 20000): cur.execute('INSERT INTO test_table1 (num_value, str_value) VALUES (%s, %s) ', (i, i)) finish_time = datetime.datetime.now() print('\nSQL elapsed time: {}'.format(finish_time - start_time))
1 回答
德玛西亚99
TA贡献1770条经验 获得超3个赞
traceback.extract_stack()
不是用Ctraceback
实现的Python内部调用。整个模块都是用Python实现的,这也是它比较慢的原因。由于通常只在调试期间需要堆栈跟踪,因此通常不考虑其性能。如果您确实需要它的高性能版本,则可能需要自己将其重新实现为 C/C++ 扩展。
添加回答
举报
0/150
提交
取消