He *_*ing 1 python optimization numpy list-comprehension
我正在使用cProfile基于列表理解处理字符串的脚本运行基准测试.我想优化的目标行看起来像这样:
signals = [('prefix' + str(day) + '_' + s) for s in signals]
Run Code Online (Sandbox Code Playgroud)
哪里day是整数.
这条特定的生产线使用了整个运行时间的33%.当然,在执行过程中它被称为百万次.
我已经试过了几个明显的替代方案,其中包括''.join('prefix', str(day), '_', s),'prefix{:}_'.format(day)和使用numpy.core.defchararray.add来连接通过创建一个前缀阵列numpy.tile有signals.它们都比列表理解慢2倍.
这条线路的速度优化还有空间吗?
这至少应该带来最小的改进:
# First precalculate the static part of the string
template = 'prefix%s_' % day + '%s'
# Then, use the %s string interpolation instead of joining strings with '+'
# -->> Note: this proved to be wrong later...
signals = [template % s for s in signals]
# Alternatively you could use map to compare efficiency (be aware of differences between python 2 and 3)
signals = map(template.__mod__, signals)
Run Code Online (Sandbox Code Playgroud)
该str.format比更昂贵的%s插值,所以我不会去尝试.
现在让我们比较一下时间.你的方法:
>>> import timeit
>>> day = 45
>>> signals = ['aaaa', 'bbbb', 'cccccc', 'dddddddddddd']
>>> timeit.timeit("[('prefix' + str(day) + '_' + s) for s in signals]", 'from __main__ import day, signals')
1.35095184709592
Run Code Online (Sandbox Code Playgroud)
我的第一个方法
>>> template = 'prefix%s_' % day + '%s'
>>> timeit.timeit("[template % s for s in signals]", 'from __main__ import template, signals')
0.7075940089748229
Run Code Online (Sandbox Code Playgroud)
我的第二种方法
>>> timeit.timeit("map(template.__mod__, signals)", 'from __main__ import template, signals')
0.9939713030159822
Run Code Online (Sandbox Code Playgroud)
因此,具有列表理解的模板的预先计算似乎获胜.还有一些事情需要考虑,例如,如果发电机对您来说足够好.
在interesing注释中指出的编辑编辑,我添加了另一个解决方案:在紧密循环内部我们只将两个字符串连接在一起,所以我们可以直接连接它们而不是%-formatting
>>> template = 'prefix%s_' % day
>>> timeit.timeit("[template + s for s in signals]", 'from __main__ import template, signals')
0.39771016975851126
Run Code Online (Sandbox Code Playgroud)
目前哪个是胜利者.