当前位置: 首页 > 知识库问答 >
问题:

对于超过64个字符的字符串,什么会影响Python字符串比较性能?

衡高寒
2023-03-14

我试图评估比较两个字符串是否会随着它们的长度增加而变慢。我的计算表明比较字符串应该需要一个摊销常数时间,但我的Python实验产生了奇怪的结果:

下面是字符串长度(1到400)与时间(毫秒)的关系图。自动垃圾收集已禁用,并且gc。在每次迭代之间运行collect。

我每次比较100万随机字符串,计算匹配如下。这个过程重复50次,然后取所有测量时间的最小值。

for index in range(COUNT):
    if v1[index] == v2[index]:
        matches += 1
    else:
        non_matches += 1

什么可能解释长度64左右突然增加?

注意:假设v1和v2是两个长度为n的随机字符串列表,COUNT是它们的长度,则可以使用下面的代码段来尝试再现该问题。

timeit.timeit("for i in range(COUNT): v1[i] == v2[i]",
  "from __main__ import COUNT, v1, v2", number=50)

进一步注意:我做了两个额外的测试:将字符串与进行比较是而不是==完全抑制了问题,性能约为210ms/1M比较。既然提到了实习,我确保在每个字符串后面添加一个空格,这应该可以防止实习;这不会改变任何事情。那么是不是除了实习之外的其他事情?

共有2个答案

隗瑞
2023-03-14

我只是在胡乱猜测,但你问的是“可能是什么”,而不是什么原因。这里有一些可能性:

  • CPU缓存线大小为64字节,较长的字符串会导致缓存未命中
顾烨磊
2023-03-14

Python可以“插入”短字符串;将它们存储在特殊缓存中,并重新使用该缓存中的字符串对象。

然后比较字符串时,它将首先测试它是否是相同的指针(例如一个内嵌字符串):

if (a == b) {
    switch (op) {
    case Py_EQ:case Py_LE:case Py_GE:
        result = Py_True;
        goto out;
// ...

只有当指针比较失败时,它才会使用大小检查和memcmp来比较字符串。

通常只会对标识符(函数名、参数、属性等)进行实习,但不会对运行时创建的字符串值进行实习。

另一个可能的罪魁祸首是字符串常量;代码中使用的字符串文本在编译时存储为常量,并在整个过程中重用;同样,只创建了一个对象,对这些对象的身份测试速度更快。

对于不相同的字符串对象,Python测试等长、等首字符,然后对内部C字符串使用memcmp()函数。如果字符串没有被插入或以其他方式重用相同的对象,那么所有其他速度特性都归结为memcmp()函数。

 类似资料:
  • 问题内容: 我从书中看到以下代码: 但没有提到为什么“一个”大于“四个”。我试过了,它小于a和b。我想知道JavaScript如何比较这些字符串。 问题答案: 因为和许多编程语言一样,字符串是按字典顺序进行比较的。 你可以认为这是一个空想家版本的字母顺序,区别在于字母排序仅覆盖了26个字符通过。

  • 问题内容: 我有一个Android应用程序,我想检查安装的应用程序名称是否与传递给包含此代码的函数的字符串匹配。代码和示例如下: 假设您打过电话,并且手机上的应用程序名称与返回的名称相同。但是,它永远不会。我记录了结果,它应该匹配,但事实并非如此。任何人都可以请问我为什么这行不通吗? 问题答案: 使用String的equals()方法代替==运算符来比较字符串: 在Java中,新手遇到的最常见错误

  • 问题内容: 我注意到,在相同的字符串中添加空格会使它们使用比较不相等,而非空格版本则比较相等。 我已经阅读了有关将字符串与和进行比较的问题。我认为这是一个不同的问题,因为空格字符正在改变行为,而不是字符串的长度。看到: 为什么在字符串中添加空格会更改此比较的结果? 问题答案: python解释器根据某些条件缓存一些字符串,第一个字符串被缓存并用于两者,而第二个则不。从in到int的小整数也是一样。

  • 如何检查一个字符串是否在另一个字符串中,但匹配项需要在前面,而不是中间或最后。例如,a="

  • 主要内容:equals() 方法,equalsIgnoreCase() 方法,equals()与==的比较,compareTo() 方法字符串比较是常见的操作,包括比较相等、比较大小、比较前缀和后缀串等。 在 Java 中,比较字符串的常用方法有 3 个:equals() 方法、equalsIgnoreCase() 方法、 compareTo() 方法。下面详细介绍这 3 个方法的使用。 equals() 方法 equals() 方法将逐个地比较两个字符串的每个字符是否相同。如果两个字符串具有相

  • 我有问题。我做了这个练习,但是我不知道如何在我的代码中解决最后三个问题。我需要打印失败,但我不能得到,因为我只得到OK OK,如果这就是全部。 有什么建议吗??