Why is concatenating strings running faster than joining them?
据我所知,"join(iterable_of_strings)是连接字符串的首选方法,因为它允许优化,避免将不可变对象重写到内存的次数超过必要次数。
在表达式中添加字符串的运行速度比在我的中等数量的操作中加入字符串要快。
我在joined上得到了大约2.9-3.2秒的时间,在我的笔记本电脑上用python 3.3运行这个代码得到了2.3-2.7秒的时间。我在谷歌上找不到一个好答案。有人能解释一下可能发生的事情吗?或者能指导我找到一个好的资源吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import uuid import time class mock: def __init__(self): self.name ="foo" self.address ="address" self.age ="age" self.primarykey = uuid.uuid4() data_list = [mock() for x in range(2000000)] def added(): my_dict_list = {} t = time.time() new_dict = { item.primarykey: item.name + item.address + item.age for item in data_list } print(time.time() - t) def joined(): my_dict_list = {} t = time.time() new_dict = { item.primarykey: ''.join([item.name, item.address, item.age]) for item in data_list } print(time.time() - t) joined() added() |
As I understand it"".join(iterable_of_strings) is the preferred way to concatenate strings because it allows for optimizations that avoid having to rewrite the immutable object to memory more times than necessary.
号
你理解有点不正确。根据您解释的原因,
但是,您没有一个不可重复的字符串。你只有三根弦。连接三个字符串的最快方法是将它们与
除非有这么多的字符串,否则
虽然并非所有的实现都有快速的连接,但我已经测试了cpython、pypy和jython,并且所有的实现都有更快的连接,或者只对几个字符串进行了同样快的连接。
本质上,您应该根据代码的清晰度在
一些时间安排:http://slides.colliberty.com/djangoconeu-2013//step-40
视频说明:http://youtu.be/50oio9onmks?T=18立方米
您看到的时间差来自创建要传递给
如果您有一个可从字符串开始的iterable,而不是一个以字符串作为属性的对象,则情况会有所不同。然后您可以直接在iterable上调用
下面是我对
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | import timeit short_strings = ["foo","bar","baz"] long_strings = [s*1000 for s in short_strings] def concat(a, b, c): return a + b + c def concat_from_list(lst): return lst[0] + lst[1] + lst[2] def join(a, b, c): return"".join([a, b, c]) def join_tuple(a, b, c): return"".join((a, b, c)) def join_from_list(lst): return"".join(lst) def test(): print("Short strings") print("{:20}{}".format("concat:", timeit.timeit(lambda: concat(*short_strings)))) print("{:20}{}".format("concat_from_list:", timeit.timeit(lambda: concat_from_list(short_strings)))) print("{:20}{}".format("join:", timeit.timeit(lambda: join(*short_strings)))) print("{:20}{}".format("join_tuple:", timeit.timeit(lambda: join_tuple(*short_strings)))) print("{:20}{} ".format("join_from_list:", timeit.timeit(lambda: join_from_list(short_strings)))) print("Long Strings") print("{:20}{}".format("concat:", timeit.timeit(lambda: concat(*long_strings)))) print("{:20}{}".format("concat_from_list:", timeit.timeit(lambda: concat_from_list(long_strings)))) print("{:20}{}".format("join:", timeit.timeit(lambda: join(*long_strings)))) print("{:20}{}".format("join_tuple:", timeit.timeit(lambda: join_tuple(*long_strings)))) print("{:20}{}".format("join_from_list:", timeit.timeit(lambda: join_from_list(long_strings)))) |
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit (AMD64)] on win32 Type"copyright","credits" or"license()" for more information. >>> ================================ RESTART ================================ >>> >>> test() Short strings concat: 0.5453461176251436 concat_from_list: 0.5185697357936024 join: 0.7099379456477868 join_tuple: 0.5900842397209949 join_from_list: 0.4177281794285359 Long Strings concat: 2.002303591571888 concat_from_list: 1.8898819841869416 join: 1.5672863477837913 join_tuple: 1.4343144915087596 join_from_list: 1.231374639083505 |
号
所以,从已经存在的列表中加入总是最快的。如果单个项目较短,则与