更快的方法.format()

时间:2012-08-11 11:34:10

标签: python performance string.format

我正在编写一个需要执行大量字符串格式化的程序,并且我注意到.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可以加起来

4 个答案:

答案 0 :(得分:4)

尝试将.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

答案 1 :(得分:4)

您也可以尝试迁移到PyPy,在cpython和PyPy中有一个关于字符串格式比较的article

答案 2 :(得分:2)

使用.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,变量abc是浮点数。

答案 3 :(得分:1)

如果浮点转换仍然是瓶颈,您可以尝试将格式设置为multiprocessing.Pool,并使用multiprocessing.map_asyncmultiprocessing.imap打印生成的字符串。这将使用计算机上的所有核心进行格式化。虽然可能是将数据传入和传出不同进程的开销掩盖了并行化格式化的改进。