性能:(比较字符串)与(转换为整数)

7

大家好:我是 Stack Overflow 的新手,对 Python 也比较陌生,但我已经写了多年的代码,想知道以下哪个性能更好。

假设我已经从 os 加载了 envioron,而环境中的标志保证是 "0" 或 "1"。

if environ["Flag"] == "1":
    do_something

或者

if int(environ["Flag"]) == 1:
    do something

乍一看,转换为整数再比较似乎会因为转换而变慢,但是我知道字符串比较也可能很慢。

有人研究过这个问题吗?

谢谢,马克。

4个回答

6
为什么不自己检查一下呢:
import timeit

print(timeit.timeit('a="1"; a == "1"', number=10000))
print(timeit.timeit('a="1"; int(a) == 1', number=10000))

我的结果是:
0.0003461789892753586
0.0019836849969578907

这表明字符串比较速度更快。

6
In [44]: timeit int("1") == 1
1000000 loops, best of 3: 380 ns per loop

In [44]: timeit "1" == "1"
10000000 loops, best of 3: 36.5 ns per loop

将字符串转换为整数始终会更慢,这是很合理的,因为您首先需要创建一个字符串,然后再将其转换为整数。 转换是最耗费时间的部分:
In [45]: timeit 1
100000000 loops, best of 3: 11.9 ns per loop

In [46]: timeit "1" 
100000000 loops, best of 3: 11 ns per loop

In [47]: timeit int("1")
1000000 loops, best of 3: 366 ns per loop

使用a = "1"创建字符串与使用a = 1 b = str(1)有所不同,这可能会让你感到困惑。

In [3]: a = 1

In [4]: timeit str(b)
10000000 loops, best of 3: 135 ns per loop

使用Python 2.7计时,使用Python 3的差别几乎相同。

输出来自我的IPython终端,使用ipython魔术timeit函数


2
其他人提到的当有疑问时,要计算时间。但是这里需要解释一下:当你比较两个字符串时,算法大致如下:
from 0 to the length of the shortest string
     if characters at this position are different
          return false
return true

因此,字符串比较的速度完全取决于字符串相等的程度。在您的示例中,您正在将其与"1"进行比较,这是一个单字符字符串。因此,在您的情况下,核心问题是:

if environ["Flag"][0] == "1"[0]

换句话说,它比较单个字节与另一个单个字节。显然,单个比较速度会很快。
在第二种情况下,您将字符串转换为int。这需要一些时间。但是如果我们假设最好的情况,并且标志始终为“0”或“1”,那么可能是这样的:
i = s[0] - ord("0")

然后您比较两个整数。整数占四个字节,而不是一个字节,但在现代芯片上可能没有关系。

但无论如何,这意味着当您比较两个字符串时,您正在进行一次比较。当您转换为int时,您正在进行转换工作,然后进行一次比较。因此,字符串比较更快。

但同样地,这是情境性的。它之所以更快,是因为您正在比较长度为1的两个字符串。比较两个ints具有恒定的速度,但比较两个字符串与较短字符串的长度成正比。

最后,从环境变量中取出标记只需要每次运行执行一次。我们谈论的是您只做一次的几百纳秒的事情。那种规模的差异只值得在运行多次的循环中担心。在这种情况下,不必担心性能,而应担心哪种更易读一些。(可能仍然是字符串比较版本。)


0

以下是一些快速脏比较。

import time

s1 = '10000000000000000000001'
s2 = '10000000000000000000002'

方法一:不将字符串强制转换为整数

  • 当数字字符串长度相等时,'1000' < '2' 是有意义的,因为按字典顺序 '1' < '2'

  • 当您在执行流程中不同时收到数字时,这是首选的。

  • 一个这样的示例场景

     t1 = time.time()
     for i in range(10000000):
        if s1<s2:
            pass
     print(time.time() - t1)
    

输出示例:

0.5940780639648438

方法二:每次与字符串比较时都进行类型转换 在处理以下情况时更可取:

  • "数字不等式涉及长度不同的数字字符串"(请注意,对于长度不同的数字字符串的相等比较,显然不需要进行类型转换)

  • 您在不同的时间收到数字,而不是一开始就全部收到,这种情况下第三种方法显然更合适。

    t1 = time.time()
    
    for i in range(10000000):
        if int(s1)<int(s2):
            pass
    print(time.time() - t1)
    

示例输出:

4.108525276184082

方法三: 每次比较字符串时进行类型转换。

n1 = int(s1)
n2 = int(s2)
t1 = time.time()
for i in range(10000000):
    if n1<n2:
        pass
print(time.time() - t1)

示例输出:

0.5334858894348145

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接