2

我正在编写一个需要进行大量字符串格式化的程序,我注意到这.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

4 回答 4

4

您也可以尝试迁移到PyPy,有一篇关于 cpython 和 PyPy 中的字符串格式比较的文章。

于 2012-08-11T11:46:39.227 回答
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
于 2012-08-11T11:39:40.430 回答
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是浮点数。

于 2012-08-11T11:37:48.643 回答
1

如果浮点转换仍然是一个瓶颈,您可能会尝试将格式转换为 a multiprocessing.Pool,并使用multiprocessing.map_asyncormultiprocessing.imap打印结果字符串。这将使用您机器上的所有内核进行格式化。尽管将数据传入和传出不同进程的开销可能掩盖了并行化格式化的改进。

于 2012-08-11T23:00:18.103 回答