我正在编写一个需要进行大量字符串格式化的程序,我注意到这.format()
会占用少量但大量的 cpu 时间。这是我使用它的方式:
str = 'vn {0:.15f} {1:.15f} {2:.15f}\n'.format(normal_array[i].x, normal_array[i].y, normal_array[i].z)
有谁知道是否有更快的方法来做到这一点,因为一小部分 X 100000 可以加起来
我正在编写一个需要进行大量字符串格式化的程序,我注意到这.format()
会占用少量但大量的 cpu 时间。这是我使用它的方式:
str = 'vn {0:.15f} {1:.15f} {2:.15f}\n'.format(normal_array[i].x, normal_array[i].y, normal_array[i].z)
有谁知道是否有更快的方法来做到这一点,因为一小部分 X 100000 可以加起来
您也可以尝试迁移到PyPy
,有一篇关于 cpython 和 PyPy 中的字符串格式比较的文章。
尝试.format
用%
表达式替换并预先计算 normal_array:
item = normal_array[i]
'vn %.15f %.15f %.15f\n' % (item.x, item.y, item.z)
同样用迭代值替换索引可以稍微提高速度:
for item in normal_array:
'vn %.15f %.15f %.15f\n' % (item.x, item.y, item.z)
基准:
def gen_data(n):
l = []
for k in xrange(n):
l.append(collections.namedtuple('normal', ('x', 'y', 'z'))(random.random(), random.random(), random.random()))
return l
if __name__ == '__main__':
times = 1000
print 'format:'
print timeit.Timer('for i in xrange(len(normal_array)):\n str = "vn {0:.15f} {1:.15f} {2:.15f}\\n".format(normal_array[i].x, normal_array[i].y, normal_array[i].z)\n',
'from __main__ import gen_data; normal_array = gen_data(1000)').timeit(times)
print '%s:'
print timeit.Timer('for i in xrange(len(normal_array)):\n str = "vn %.15f %.15f %.15f\\n".format(normal_array[i].x, normal_array[i].y, normal_array[i].z)\n',
'from __main__ import gen_data; normal_array = gen_data(1000)').timeit(times)
print '%s+iteration:'
print timeit.Timer('for o in normal_array:\n str = "vn %.15f %.15f %.15f\\n".format(o.x, o.y, o.z)\n',
'from __main__ import gen_data; normal_array = gen_data(1000)').timeit(times)
结果(越低越好)
format:
5.34718108177
%s:
1.30601406097
%s+iteration:
1.23484301567
.format()
通过替换%
格式指令来尝试这种(老派)方法:
str = 'vn %.15f %.15f %.15f\n' % (normal_array[i].x, normal_array[i].y, normal_array[i].z )
似乎使用%
会更快:
timeit str='%.15f %.15f %.15f\n' % (a, b, c)
100000 loops, best of 3: 4.99 us per loop
timeit str2='{:.15f} {:.15f} {:.15f}\n'.format(a, b, c)
100000 loops, best of 3: 5.97 us per loop
XP SP2 下的 Python v 2.7.2、变量a
、b
和c
是浮点数。
如果浮点转换仍然是一个瓶颈,您可能会尝试将格式转换为 a multiprocessing.Pool
,并使用multiprocessing.map_async
ormultiprocessing.imap
打印结果字符串。这将使用您机器上的所有内核进行格式化。尽管将数据传入和传出不同进程的开销可能掩盖了并行化格式化的改进。