Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

faster way to do .format()

I'm writing a program that needs to do a lot of string formatting and I have noticed that .format() is taking a small but significant amount of cpu time. Here's how I'm using it:

str = 'vn {0:.15f} {1:.15f} {2:.15f}\n'.format(normal_array[i].x, normal_array[i].y, normal_array[i].z)

Does anyone know if there is even a slightly faster way to do this as a small fraction X 100000 can add up

like image 955
jonathan topf Avatar asked Nov 23 '25 16:11

jonathan topf


2 Answers

Try to replace .format with % expression and pre-calculate normal_array:

item = normal_array[i]
'vn %.15f %.15f %.15f\n' % (item.x, item.y, item.z)

Also replacing indexes with iteration over values can slightly improve speed:

for item in normal_array:
    'vn %.15f %.15f %.15f\n' % (item.x, item.y, item.z)

Benchmark:

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)

Results (lower is better)

format:
5.34718108177
%s:
1.30601406097
%s+iteration:
1.23484301567
like image 164
Vladimir Avatar answered Nov 25 '25 07:11

Vladimir


Also you can try to migrate to PyPy, there was an article about string formatting comparison in cpython and PyPy.

like image 45
Fedor Gogolev Avatar answered Nov 25 '25 06:11

Fedor Gogolev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!