我编写了一个简单的函数,它接收一些实现.index()的函数和一个要检查的字符列表。
我的假设是,由于字符串和元组都是不可变的,因此它们具有相似的性能(或者至少,元组的性能会超过列表)。相反,元组似乎等同于列表。那是为什么?
from string import ascii_lowercase
from random import randint
from timeit import Timer
def check_index(st, guesses):
for i in guesses:
st.index(i)
if __name__ == "__main__":
num_checks = 10
lst = [n for n in ascii_lowercase]
st = ascii_lowercase
tup = tuple(lst)
guesses = [ascii_lowercase[randint(0, len(ascii_lowercase)-1)]
for n in xrange(num_checks)]
def run_string():
check_index(st, guesses)
def run_list():
check_index(lst, guesses)
def run_tuple():
check_index(tup, guesses)
t2 = Timer(run_list)
print "List", t2.timeit()
t3 = Timer(run_tuple)
print "Tuple", t3.timeit()
t = Timer(run_string)
print "String", t.timeit()
示例运行(Python 2.7.6)
List 5.26431703568
Tuple 5.28769207001
String 3.16058015823
List 5.30263400078
Tuple 5.17412590981
String 3.17718791962
List 5.21962976456
Tuple 5.35261583328
String 3.22652792931
答案 0 :(得分:3)
tl; dr:字符串index
来电有很多优化,并且不必进行丰富的比较"。 list
和tuple
s 做都必须这样做;可变性并不重要。
如果您打开stringobject.c
,则可以看到index
来电string_find_internal
,呼叫stringlib_find_slice
,呼叫stringlib_find
,呼叫{{1} }}
fastsearch
在评论中指向this page,如果您有兴趣,请查看它。关于如何在python中实现Boyer-Moore子字符串搜索,它有一些有趣的内容。但这在你的1字符子字符串搜索中并不重要,fastsearch
显式特殊情况:
fastsearch
非常紧的循环,紧密的循环在C中非常快。
好的,这涵盖了字符串。那么 } else if (mode == FAST_SEARCH) {
for (i = 0; i < n; i++)
if (s[i] == p[0])
return i;
}
和tuple
s呢?
这次要简单得多;这是两种类型必须执行的循环:
list
这个循环不必仅仅检查与for (i = start; i < stop && i < Py_SIZE(self); i++) {
int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
if (cmp > 0)
return PyInt_FromSsize_t(i);
的相等性,而是必须在循环中每次迭代都进行PyObject_RichCompareBool
。我没有太多具体细节进入代码(如果你很好奇的话,请查看object.c
),但实际上这必须进行一些类型检查,然后查看这些类型是否实现了丰富的比较,然后调用该比较函数,检查它是否返回==
单例,最后返回比较。
因此,该循环是NotImplemented
调用中完成的大部分工作,并且列表和元组都必须这样做。字符串可以作弊。
答案 1 :(得分:1)
index
将每个元素与给定对象进行比较。由于元组存储像列出python对象,因此比较需要相同的时间。字符串更快,因为比较字符比比较对象更快。