楼主: lastwinner

[参考文档] Python 研究(Dive Into Python)

[复制链接]
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
371#
 楼主| 发表于 2006-7-20 01:49 | 只看该作者
18.6. 优化字符串操作
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

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
372#
 楼主| 发表于 2006-7-20 01:49 | 只看该作者
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 略微慢些。 性能优化并不总是一致的,对于一个情况快些,却可能对另外一些情况慢些。 就此而言,大多数情况将会从改变中获益,所以就改吧,但是别忘了原则。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
373#
 楼主| 发表于 2006-7-20 01:49 | 只看该作者
最后仍很重要的是,让我们检测算法的最后两步:以零补齐短结果和截短超过四字符的长结果。你在 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

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
374#
 楼主| 发表于 2006-7-20 01:49 | 只看该作者
最后,还有一件事可以另这三行运行的更快:你可以把它们合并为一行。 看一眼 soundex/stage4/soundex4d.py:

    return (digits2.replace('9', '') + '000')[:4]
在 soundex4d.py 中把所有代码放在一行可以比 soundex4c.py 稍微快那么一点:

C:\samples\soundex\stage4>python soundex4d.py
Woo             W000 4.93624105857
Pilgrim         P426 7.19747593619
Flingjingwaller F452 10.5490700634
它非常难懂,而且优化也不明显。 这值得吗? 我希望你有很好的见解。 性能并不是一切。 你在优化方面的努力应该与程序的可读性和可维护性相平衡。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
375#
 楼主| 发表于 2006-7-20 01:50 | 只看该作者
18.7. 小结
这一章展示了性能优化的几个重要方面,这里是就 Python 而言,但它们却普遍使用。
  • 如果你要在正则表达式和编写循环间抉择,选择正则表达式。 正则表达式因其是以 C 语言编译的可以本能地在你的计算机上运行,你的循环却以 Python 编写需要通过 Python 解释器运行。
  • 如果你需要在正则表达式和字符串方法间抉择,选择字符串方法。 它们都是以 C 编译的,所以选取简单的。
  • 字典查找的通常应用很快,但是 string.maketrans 之类的特殊函数和 isalpha() 之类的字符串方法更快。如果 Python 有定制方法给你用,就使它吧!
  • 别太聪明了。 有时一些明显的算法是最快的。
  • 不要太迷恋性能优化,性能并不是一切。

最后一点太重要了,这章中你令这个程序三倍的提速并且另百万次的调用节省 20 秒。 太棒了! 现在思考一下:在那百万次的函数调用中,有多少秒花在周边应用程序等待数据连结上?花在磁盘输入/输出上?花在等待用户输入上? 不要在过度优化算法上花时间,从而忽略了其它地方可以做的明显改进。 开发你编写运行良好的 Python 代码的直觉,如果发现明显的失误则修正它们,并不对其它部分过分操作。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
376#
 楼主| 发表于 2006-7-20 01:52 | 只看该作者
附录 A. 进一步阅读
第 1 章 安装 Python

    第 2 章 第一个 Python 程序

    使用道具 举报

    回复
    论坛徽章:
    484
    ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
    377#
     楼主| 发表于 2006-7-20 01:53 | 只看该作者
    第 3 章 内置数据类型

    使用道具 举报

    回复
    论坛徽章:
    484
    ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
    378#
     楼主| 发表于 2006-7-20 01:54 | 只看该作者

    使用道具 举报

    回复
    论坛徽章:
    484
    ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
    379#
     楼主| 发表于 2006-7-20 01:54 | 只看该作者

    使用道具 举报

    回复
    论坛徽章:
    484
    ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
    380#
     楼主| 发表于 2006-7-20 01:54 | 只看该作者

    使用道具 举报

    回复

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则 发表回复

    TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
      ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
      ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
    CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
    京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
      
    快速回复 返回顶部 返回列表