繁体   English   中英

Python字符串格式化太慢

[英]Python string formatting too slow

我使用下面的代码来记录一个映射,当它仅包含零时它是快速的,但是一旦映射中有实际数据,它就会变得令人难以忍受的缓慢……有什么方法可以更快地这样做吗?

log_file = open('testfile', 'w')
for i, x in ((i, start + i * interval) for i in range(length)):
    log_file.write('%-5d %8.3f %13g %13g %13g %13g %13g %13g\n' % (i, x,
        map[0][i], map[1][i], map[2][i], map[3][i], map[4][i], map[5][i]))

建议您使用cProfile模块运行代码, cProfile结果进行后处理,如http://docs.python.org/library/profile.html所述 这将使您确切知道调用str.__mod__进行字符串格式化所花费的时间,以及执行其他操作所花费的时间,例如编写文件以及对map[0][i]进行__getitem__查找等等。 。

首先,我检查了%是否有反引号。 % 是比较快的。 然后我检查了%(元组)是否与'string'.format()相对。 最初的错误使我认为它更快。 但不是。 % 是比较快的。

因此,您已经在以Python最快的方式进行了大量的浮点到字符串转换。

下面的演示代码是丑陋的演示代码。 请不要教我关于xrange与range或其他方法的比较。 KThxBye。

我的即席且高度不科学的测试表明,对于下面的测试代码,带有(a)在Linux上的Python 2.5上执行%(1.234,)操作比在Linux上的%(1.234,...)操作上更快。尝试在2.6之前的python版本上使用'string'.format()无效。 等等。

# this code should never be used in production.
# should work on linux and windows now.

import random
import timeit
import os
import tempfile


start = 0
interval = 0.1

amap = [] # list of lists
tmap = [] # list of tuples

def r():
    return random.random()*500

for i in xrange(0,10000):
        amap.append ( [r(),r(),r(),r(),r(),r()] )

for i in xrange(0,10000):
        tmap.append ( (r(),r(),r(),r(),r(),r()) )




def testme_percent():
    log_file = tempfile.TemporaryFile()
    try:
        for qmap in amap:
            s = '%g %g %g %g %g %g \n' % (qmap[0], qmap[1], qmap[2], qmap[3], qmap[4], qmap[5]) 
            log_file.write( s)
    finally:
        log_file.close();

def testme_tuple_percent():
    log_file = tempfile.TemporaryFile()
    try:    
        for qtup in tmap:
            s = '%g %g %g %g %g %g \n' % qtup
            log_file.write( s );
    finally:
        log_file.close();

def testme_backquotes_rule_yeah_baby():
    log_file = tempfile.TemporaryFile()
    try:
        for qmap in amap:
            s = `qmap`+'\n'
            log_file.write( s );
    finally:
        log_file.close();        

def testme_the_new_way_to_format():
    log_file = tempfile.TemporaryFile()
    try:
        for qmap in amap:
            s = '{0} {1} {2} {3} {4} {5} \n'.format(qmap[0], qmap[1], qmap[2], qmap[3], qmap[4], qmap[5]) 
            log_file.write( s );
    finally:
        log_file.close();

# python 2.5 helper
default_number = 50 
def _xtimeit(stmt="pass",  timer=timeit.default_timer,
           number=default_number):
    """quick and dirty"""
    if stmt<>"pass":
        stmtcall = stmt+"()"
        ssetup = "from __main__ import "+stmt
    else:
        stmtcall = stmt
        ssetup = "pass"
    t = timeit.Timer(stmtcall,setup=ssetup)
    try:
      return t.timeit(number)
    except:
      t.print_exc()


# no formatting operation in testme2

print "now timing variations on a theme"

#times = []
#for i in range(0,10):

n0 = _xtimeit( "pass",number=50)
print "pass = ",n0

n1 = _xtimeit( "testme_percent",number=50);
print "old style % formatting=",n1

n2 = _xtimeit( "testme_tuple_percent",number=50);
print "old style % formatting with tuples=",n2

n3 = _xtimeit( "testme_backquotes_rule_yeah_baby",number=50);
print "backquotes=",n3

n4 = _xtimeit( "testme_the_new_way_to_format",number=50);
print "new str.format conversion=",n4


#        times.append( n);




print "done"    

我认为您可以通过在其他任何地方构建浮点数TUPLES来优化您的代码,无论您在哪个地方构建该地图,首先构建元组列表,然后以这种方式应用fmt_string%元组:

for tup in mytups:
    log_file.write( fmt_str % tup )

通过将for-tuple部分从for循环中删除,我能够将8.7秒减少到8.5秒。 没什么。 那里的大个子有浮点格式,我相信这总是很昂贵的。

选择:

您是否考虑过不编写诸如文本之类的庞大日志,而是使用可用的最快“持久性”方法保存它们,然后编写一个简短的实用程序以在需要时将其转储为文本? 有些人将NumPy与非常大的数字数据集一起使用,而且似乎不愿意使用逐行转储来存储其内容。 看到:

http://thsant.blogspot.com/2007/11/saving-numpy-arrays-which-is-fastest.html

不希望涉入优化此代码的麻烦,我会像这样编写代码:

log_file = open('testfile', 'w')
x = start
map_iter = zip(range(length), map[0], map[1], map[2], map[3], map[4], map[5])
fmt = '%-5d %8.3f %13g %13g %13g %13g %13g %13g\n'
for i, m0, m1, m2, m3, m4, m5 in mapiter:
    s = fmt % (i, x, m0, m1, m2, m3, m4, m5)
    log_file.write(s)
    x += interval

但我会建议不要在python内置函数之后给变量命名,例如map

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM