您在这里:首页 > 深入 Python > 性能调优 > 优化字符串操作 | << >> | ||||
深入 Python从 Python 新手到专家 |
Soundex 算法的最后一步是用零填充短结果,并截断长结果。实现此目的的最佳方法是什么?
这是我们目前所做的,取自 soundex/stage2/soundex2c.py
digits3 = re.sub('9', '', digits2) while len(digits3) < 4: digits3 += "0" return digits3[:4]
以下是 soundex2c.py 的结果
C:\samples\soundex\stage2>python soundex2c.py Woo W000 12.6070768771 Pilgrim P426 14.4033353401 Flingjingwaller F452 19.7774882003
首先要考虑的是用循环替换正则表达式。这段代码来自 soundex/stage4/soundex4a.py
digits3 = '' for d in digits2: if d != '9': digits3 += d
soundex4a.py 是否更快?是的,它更快
C:\samples\soundex\stage4>python soundex4a.py Woo W000 6.62865531792 Pilgrim P426 9.02247576158 Flingjingwaller F452 13.6328416042
但是等等。使用循环从字符串中删除字符?我们可以使用一个简单的字符串方法来做到这一点。以下是 soundex/stage4/soundex4b.py
digits3 = digits2.replace('9', '')
soundex4b.py 是否更快?这是一个有趣的问题。这取决于输入
C:\samples\soundex\stage4>python soundex4b.py Woo W000 6.75477414029 Pilgrim P426 7.56652144337 Flingjingwaller F452 10.8727729362
对于大多数名称,soundex4b.py 中的字符串方法比循环更快,但在简单情况下(非常短的名称),它实际上比 soundex4a.py 稍慢。性能优化并不总是统一的;使一种情况更快的调整有时会使其他情况更慢。在这种情况下,大多数情况都将受益于此更改,因此我们将其保留,但该原则是需要记住的重要原则。
最后但并非最不重要的一点是,让我们检查一下算法的最后两个步骤:用零填充短结果,以及将长结果截断为四个字符。您在 soundex4b.py 中看到的代码就是这样做的,但效率极低。看看 soundex/stage4/soundex4c.py 就明白了
digits3 += '000' return digits3[:4]
为什么我们需要一个 while 循环来填充结果?我们事先知道要将结果截断为四个字符,并且我们知道我们至少已经有一个字符(初始字母,它从原始 source 变量传递而未更改)。这意味着我们可以简单地在输出中添加三个零,然后将其截断。不要拘泥于问题的措辞;稍微换个角度看待问题可能会找到更简单的解决方案。
通过删除 while 循环,我们在 soundex4c.py 中获得了多少速度?非常显著
C:\samples\soundex\stage4>python soundex4c.py Woo W000 4.89129791636 Pilgrim P426 7.30642134685 Flingjingwaller F452 10.689832367
最后,您还可以对这三行代码做一件事,使它们更快:您可以将它们合并为一行。看看 soundex/stage4/soundex4d.py
return (digits2.replace('9', '') + '000')[:4]
将所有这些代码放在 soundex4d.py 的一行中,速度 barely 比 soundex4c.py 快
C:\samples\soundex\stage4>python soundex4d.py Woo W000 4.93624105857 Pilgrim P426 7.19747593619 Flingjingwaller F452 10.5490700634
它的可读性也大大降低,而且性能提升不大。这样做值得吗?我希望你有好的注释。性能并不是一切。您的优化工作必须始终与程序可读性和可维护性方面的威胁相平衡。
<< 优化列表操作 |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
总结 >> |