【发布时间】:2025-12-15 22:40:01
【问题描述】:
我很好奇为什么在我的代码中删除一行会显着提高性能。该函数本身采用字典并删除作为其他键的子字符串的所有键。
使我的代码变慢的行是:
if sub in reduced_dict and sub2 in reduced_dict:
这是我的功能:
def reduced(dictionary):
reduced_dict = dictionary.copy()
len_dict = defaultdict(list)
for key in dictionary:
len_dict[len(key)].append(key)
start_time = time.time()
for key, subs in len_dict.items():
for key2, subs2 in len_dict.items():
if key2 > key:
for sub in subs:
for sub2 in subs2:
if sub in reduced_dict and sub2 in reduced_dict: # Removing this line gives a significant performance boost
if sub in sub2:
reduced_dict.pop(sub, 0)
print time.time() - start_time
return reduced_dict
该函数多次检查 sub 是否在 sub2 中。我假设如果我检查了已经进行的比较,我会节省自己的时间。情况似乎并非如此。为什么在字典中查找的常数时间函数会减慢我的速度?
我是初学者,所以我对概念很感兴趣。
当我测试有问题的行是否返回 False 时,似乎确实如此。我已经用以下方法对此进行了测试
def reduced(dictionary):
reduced_dict = dictionary.copy()
len_dict = defaultdict(list)
for key in dictionary:
len_dict[len(key)].append(key)
start_time = time.time()
for key, subs in len_dict.items():
for key2, subs2 in len_dict.items():
if key2 > key:
for sub in subs:
for sub2 in subs2:
if sub not in reduced_dict or sub2 not in reduced_dict:
print 'not present' # This line prints many thousands of times
if sub in sub2:
reduced_dict.pop(sub, 0)
print time.time() - start_time
return reduced_dict
对于函数输入字典中的 14,805 个键:
- 19.6360001564 秒。没有线
- 33.1449999809 秒。用线
这里有 3 个字典示例。 Biggest sample dictionary with 14805 keys、medium sample dictionary 和 smaller sample dictionary
对于最大示例字典中的前 14,000 个键,我绘制了以秒 (Y) 为单位的时间与以键数 (X) 为单位的输入大小的关系图。看来所有这些函数都具有指数复杂性。
- John Zwinck answer 这个问题
- 马特我的算法这个问题没有字典 比较
- Matt exponential 是我第一次尝试解决这个问题。这花了 76 秒
- Matt compare 是这个问题中的算法,带有 dict 比较线
- tdelaney solution 这个问题。算法 1 和 2 按顺序排列
- georg solution 来自我提出的一个相关问题
接受的答案在明显的线性时间内执行。
我很惊讶地发现输入大小存在魔法比率,其中 dict 查找的运行时间 == 字符串搜索。
【问题讨论】:
-
你能包含你用来测试这个的示例字典吗?此外,使用
time.time()来衡量这一点通常不够准确。您应该改用timeit模块。 -
这里有 2 个字典示例。第一个较长justpaste.it/festival_dict,第二个较短justpaste.it/ATGC
-
由于四重嵌套的“for”循环,您的代码可能比其他任何东西都慢。 :)
-
@John Zwinck 在尝试解决相同问题时,上面的代码运行速度比我之前的问题中的解决方案快得多。 *.com/a/25422647/3761932 我会尝试解决嵌套问题,但这是另一个问题。
-
您描述了一种对键进行操作的算法,但您的代码对值进行了操作。这只是一个错字吗?
标签: python performance algorithm dictionary