尝试在python中查找字符串的长度时获得不一致的结果(使用timeit)

时间:2015-07-23 17:43:09

标签: python string compare string-length timeit

我试图通过将字符串与不同的字符串进行比较来查找字符串的长度。 Python比较字符串如下:

if (op == Py_EQ) {
    /* Supporting Py_NE here as well does not save
       much time, since Py_NE is rarely used.  */
    if (Py_SIZE(a) == Py_SIZE(b)
        && (a->ob_sval[0] == b->ob_sval[0]
        && memcmp(a->ob_sval, b->ob_sval, Py_SIZE(a)) == 0)) {
        result = Py_True;
    } else {
        result = Py_False;
    }
    goto out;
}

我看到它的方式(也许我错了),假设花费较少的时间来比较长度不同的字符串的长度不同的字符串。 我已经建立了这个功能:

def find_length(string, possible_length = xrange(1, 33)):
    l = []
    for i in possible_length:
        temp = '*' * i
        l.append(timeit.timeit(lambda: temp == string, number=10**5))
    return l.index(max(l)) + 1

当像这样使用它时:print find_length('test')我期望得到4的结果,但我得到(在我跑了5次之后):20,10,26,22,8。 首先我想也许是因为我处理这么短的时间10 ^ 5还不够,但它给出了相同的结果(不是20,10,26 ......但结果也不一致)。 有没有人在我的代码/逻辑中发现错误?

1 个答案:

答案 0 :(得分:0)

您正在测试太短的字符串,无法说明测试长度和内容之间的速度差异。此外,通过测试第一个字符,可以看出您的temp字符串不相等。

因此,您只需测试len(temp) == len(string),否则您只需添加测试以查看是否temp[0] == string[0]。这确实是一个非常小的差异。

使用长随机字符串,并使用相同字符串的片段进行测试,以便它们几乎相等:

>>> import random
>>> import string
>>> from timeit import timeit
>>> target = ''.join(random.choice(string.ascii_letters) for _ in range(10000))
>>> almost_equal = target[:-1]
>>> equal = almost_equal + target[-1]
>>> timeit(lambda: target == almost_equal)
0.11822915077209473
>>> timeit(lambda: target == equal)
0.48569512367248535

现在区别在于测试一个10000字符的字符串和一个长度为9999个字符的字符串,并且在结尾处缺少一个字符时,除了,而不是测试完全相等的字符串。第二次测试的时间超过4倍。

通过测试一个相等的字符串,你遇到了最糟糕的情况;必须比较10000个中的每个字符以确定字符串确实具有相同的值。

如果您希望通过针对越来越长的字符串进行测试来推断字符串长度并找到花费时间最长的比较,那么您根本无法做到。仅仅测试长度和确定一个同样长的字符串值之间没有足够的区别,至少在检测到它们与单独的第一个字符不相等时是不可能的。