Python 为什么方法这么慢? < >我明白,在C++语言中,为什么调用类中定义的虚方法比调用非虚方法慢,必须通过动态调度表查找正确的调用来实现。

Python 为什么方法这么慢? < >我明白,在C++语言中,为什么调用类中定义的虚方法比调用非虚方法慢,必须通过动态调度表查找正确的调用来实现。,python,function,Python,Function,但在Python中,如果我有: list_of_sets = generate_a_list_containg_a_bunch_of_sets() intersection_of_all = reduce(list_of_sets[0].intersection, list_of_sets) 在我的实验中,这比以下速度慢了40%左右: list_of_sets = generate_a_list_containg_a_bunch_of_sets() intersection_of_all =

但在Python中,如果我有:

list_of_sets = generate_a_list_containg_a_bunch_of_sets()
intersection_of_all = reduce(list_of_sets[0].intersection, list_of_sets)
在我的实验中,这比以下速度慢了40%左右:

list_of_sets = generate_a_list_containg_a_bunch_of_sets()
intersection_of_all = reduce(set.intersection, list_of_sets)
我不明白的是,为什么它会慢得多,我认为在调用reduce时会发生方法查找,所以reduce内部实际上调用了交集方法的地方不需要再次查找,只需重复使用相同的方法引用即可


有人能说明我的理解哪里有缺陷吗?

这与方法绑定等完全无关。第一个版本在每次迭代中计算三个集合的交集,而第二个版本只与两个集合相交。如果我们使用显式循环,这很容易看出

备选案文1:

intersection = list_of_sets[0]
for s in list_of_sets[1:]:
    intersection = list_of_sets[0].intersection(intersection, s)
备选案文2:

intersection = list_of_sets[0]
for s in list_of_sets[1:]:
    intersection = set.intersection(intersection, s)
你现在同意Guido的观点吗

请注意,这可能会更快:

intersection = list_of_sets[0]
for s in list_of_sets[1:]:
    intersection.intersection_update(s)

这与方法绑定等完全无关。第一个版本在每次迭代中计算三个集合的交集,而第二个版本只与两个集合相交。如果我们使用显式循环,这很容易看出

备选案文1:

intersection = list_of_sets[0]
for s in list_of_sets[1:]:
    intersection = list_of_sets[0].intersection(intersection, s)
备选案文2:

intersection = list_of_sets[0]
for s in list_of_sets[1:]:
    intersection = set.intersection(intersection, s)
你现在同意Guido的观点吗

请注意,这可能会更快:

intersection = list_of_sets[0]
for s in list_of_sets[1:]:
    intersection.intersection_update(s)

你看到很多小的还是几个大的有这种区别吗?我认为在第一种情况下,绑定问题很重要,但在后一种情况下,当实际的交叉口工作占主导地位时,绑定问题就不重要了。我看到两个相互矛盾的答案,其中一个是两次,但我不知道哪一个是正确的。这是随机生成的一个大约10组的小列表和一个大约100组的中列表。斯文在下面的回答中解释了原因。你看到许多小的集合有这种差异吗,还是一些大的集合有这种差异?我认为在第一种情况下,绑定问题很重要,但在后一种情况下,当实际的交叉口工作占主导地位时,绑定问题就不重要了。我看到两个相互矛盾的答案,其中一个是两次,但我不知道哪一个是正确的。这是随机生成的一个大约10组的小列表和一个大约100组的中列表。斯文在下面的回答中解释了原因。谢谢是的,使用交集_udpate进行循环比使用set.intersection进行reduce快约3%。@AdamParkin:因为我本来以为非平凡情况下会有更大的差异,所以。事实上,我发现循环版本的速度是reduce版本的两倍多。不必在每次迭代中都创建一个新集合,应该会有所不同!这似乎是因为我的测试集太小了,只有大约100个测试集,每个测试集大约有30个项目。@AdamParkin:可能很快交叉点就空了。我确保所有的集合都有大量相同的元素。谢谢是的,使用交集_udpate进行循环比使用set.intersection进行reduce快约3%。@AdamParkin:因为我本来以为非平凡情况下会有更大的差异,所以。事实上,我发现循环版本的速度是reduce版本的两倍多。不必在每次迭代中都创建一个新集合,应该会有所不同!这似乎是因为我的测试集太小了,只有大约100个测试集,每个测试集大约有30个项目。@AdamParkin:可能很快交叉点就空了。我确保所有集合都有大量相同的元素。