You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python sys.intern字典查找无性能提升:用法有误还是测试有问题?

sys.intern对字典查找性能的测试疑问

我好奇Python的sys.intern对字典查找的性能提升效果,为此实现了两组测试代码:

未使用字符串驻留的测试

import random
from uuid import uuid4

keys = [str(uuid4()) for _ in range(1_000_000)]
values = [random.random() for _ in range(1_000_000)]
my_dict = dict(zip(keys, values))
keys_sample = random.choices(keys, k=50_000)


def get_values(d, ks):
    return [d[k] for k in ks]

使用IPython测试结果:

%timeit get_values(my_dict, keys_sample)
8.92 ms ± 17.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

使用字符串驻留的测试

import sys
import random
from uuid import uuid4

keys = [sys.intern(str(uuid4())) for _ in range(1_000_000)]
values = [random.random() for _ in range(1_000_000)]
my_dict = dict(zip(keys, values))
keys_sample = random.choices(keys, k=50_000)


def get_values(d, ks):
    return [d[k] for k in ks]

测试结果:

%timeit get_values(my_dict, keys_sample)
8.83 ms ± 17.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

两种情况无显著差异,我尝试增大字典规模和采样量,结果仍持平。请问我是否错误使用了sys.intern,还是测试存在缺陷?


问题分析

你的测试没有体现出sys.intern的优势,核心问题出在测试用例的设计上:

  • 你用来查找的keys_sample是直接从字典已有的keys列表中选取的,不管有没有调用sys.intern,这些采样的key和字典中的key都是同一个内存对象。字典查找时,当哈希值匹配后,会先做对象身份比较(is),如果是同一个对象就直接命中,不需要再逐字符比较字符串内容。这种场景下,sys.intern完全没发挥作用。

  • sys.intern的性能收益体现在:当你用内容相同但内存地址不同的字符串去字典中查找时,intern过的字符串会让这些重复内容的字符串指向同一个对象,此时查找时的身份比较会直接通过,避免了耗时的逐字符字符串相等校验。

修正后的测试方案

要验证sys.intern的效果,需要构造“内容相同但独立创建的字符串”作为查找键,比如:

# 未使用intern的测试修改版
import random
from uuid import uuid4, UUID

keys = [str(uuid4()) for _ in range(1_000_000)]
values = [random.random() for _ in range(1_000_000)]
my_dict = dict(zip(keys, values))
# 重新生成与原key内容相同但新的字符串对象
keys_sample = [str(UUID(k)) for k in random.choices(keys, k=50_000)]

def get_values(d, ks):
    return [d[k] for k in ks]
# 使用intern的测试修改版
import sys
import random
from uuid import uuid4, UUID

keys = [sys.intern(str(uuid4())) for _ in range(1_000_000)]
values = [random.random() for _ in range(1_000_000)]
my_dict = dict(zip(keys, values))
# 重新生成与原key内容相同但新的字符串对象,同时intern
keys_sample = [sys.intern(str(UUID(k))) for k in random.choices(keys, k=50_000)]

def get_values(d, ks):
    return [d[k] for k in ks]

此时再运行%timeit,就能看到两组测试的性能差异——使用sys.intern的版本会因为字符串身份直接匹配,避免逐字符比较,从而更快完成查找。

你没有错误使用sys.intern,只是测试场景没有触发它能发挥作用的条件。


内容的提问来源于stack exchange,提问作者Sergi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:15:25