Python中连接字符串最有效的方式

众所周知,Python编程语言的咒语之一就是,“有且只有一种方式达到目的。”(在你的Python交互命令行使用“import this”来查看完整列表。)但是,往往很多时候,你有无数的方式选择来达到目的。在这种情况下,我们无法明显看出哪种方式是最好的。

首先,让我们回忆一下Python为我们提供了这几种方法来连接字符串。我们可以用+运算符,例如:

>> "ABC" + "DEF"

"ABCDEF"

我们也可以用%运算符,它可以做的不只是连接,但仍然是一个合理的选项:

>>> “%S%S” %( "ABC", "DEF")

"ABCDEF"

正如我在以前的博客文章已经提到,我们也有一个更现代的方式做到这一点,那就是str.format方法:

>>> " ".format(X, Y)

"ABCDEF"

正如%操作符,str.format方法远比简单的连接更强大。但我想,这会让我深入理解相对速度。

现在,我们如何计时呢?在Jupyter(又名IPython中),我们可以使用神奇的“timeit”命令来运行代码。因此,我写了四大功能,其中每个都以不同的方式连接字符串。我故意使用全局变量(命名为“X”和“Y”),以包含原始字符串,和一个局部变量“Z”,来存放结果。结果随后由函数返回。(我们可以稍微放开一点“X”和“Y”的值和定义。)

我要指出,concat3和concat4几乎是相同的,因为它们都使用str.format方法。第一个使用参数的隐式位置,而第二个使用显式的位置。我决定,既然我已在做基准字符串连接测试,我不妨也看看当给出参数的索引时是否有任何速度差异。

然后我定义了两个全局变量:

X = "ABC"

Y = "DEF"

最后,我运行每个函数并计时:

%timeit concat1()

%timeit concat2()

%timeit concat3()

%timeit concat4()

结果如下:

concat1:153ns/loop

concat1:275ns/loop

concat1:398ns/loop

concat1:393ns/loop

从这个基准测试中,我们可以看到,concat1,它采用+,比任何其他的方法显著更快。这有点遗憾,因为我是多么爱用str.format - 但它也意味着,如果我做一大堆的字符串处理,我应该坚持+,这可能包含更少的功能,但远快于其他方式。

问题是,上述基准测试可能是有点问题的,因为我们使用短字符串。在Python中非常短的字符串是“被约束的”,这意味着它们被定义一次,然后保存在一个表中,这样他们不需要再次进行分配,并重新创建。毕竟,因为字符串是不可变的,为什么我们不止一次创建“ABC”呢?我们可以只引用创建的第一个“ABC”。

这可能会搞乱我们的基准测试。但是,试着检查更大的字符串也很好。幸运的是,我们使用全局变量 - 因此,通过改变这些全局变量的定义,我们可以运行我们的基准测试,并确保没有发生约束:

X = "ABC" * 10000

y = "DEF" * 10000

现在,当我们再次测试函数,这时我们得到:

concat1:2.64μs/loop

concat2:3.09μs/loop

concat3:3.33μs/loop

concat4:3.48μs/loop

每个循环所花的时间很多 - 但我们看到,我们的+操作符仍然是最快的。虽然差别没有那么巨大,但是依然是相当明显和显著。

那么如果我们不再使用全局变量,而是在函数中指定字符串呢?会有所不同吗?几乎可以肯定不是,但值得快速测试一下:

而我们最终的结果是:

concat1:4.89μs/loop

concat2:5.78μs/loop

concat3:6.22μs/loop

concat4:6.19μs/loop

再一次,我们看到,+操作符是最大赢家,但它的优势没有操作短字符串时那么明显了。 str.format方法明显缩短。我们可以看到,对于str.format方法来说,无论使用“ ”还是“{} {}”格式,基本上没有差异。

经过思考,这不足为奇。毕竟,+是一个非常简单的操作,而%和str.format做得更多。此外,str.format是一种方法,这意味着它将会有更大的开销。

现在,我也可以多跑几个测试 - 例如,有两个以上的字符串。但我认为,这表明至少在一定程度+是Python实现字符串连接的最快方式。此外,它表明我们可以快速,轻松且容易地做基准测试,进行各种实验,以便帮助我们理解什么是Python中的最佳实践。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181008A1XGD900?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券