From 9ec47ae70bdd65d3f2fc2e23af3d66c8ac644c66 Mon Sep 17 00:00:00 2001 From: mec2cod Date: Mon, 17 Apr 2017 16:09:58 +0800 Subject: [PATCH] finish 201770403 Yes Python is Slow and I Dont Care.md --- ...0403 Yes Python is Slow and I Dont Care.md | 78 +++++++++++++++++-- 1 file changed, 71 insertions(+), 7 deletions(-) diff --git a/translated/tech/20170403 Yes Python is Slow and I Dont Care.md b/translated/tech/20170403 Yes Python is Slow and I Dont Care.md index 95f83385c3..cfd4d2d43e 100644 --- a/translated/tech/20170403 Yes Python is Slow and I Dont Care.md +++ b/translated/tech/20170403 Yes Python is Slow and I Dont Care.md @@ -1,4 +1,4 @@ -python 是慢,但是爷就喜欢它 +python 是慢,但我并不关心 ===================================== ### 对追求生产率而牺牲性能的怒吼 @@ -11,11 +11,11 @@ python 是慢,但是爷就喜欢它 过去的情形是,程序需要花费很长的时间来运行,CPU 比较贵,内存也很贵。程序的运行时间是一个很重要的指标。计算机非常的昂贵,计算机运行所需要的电也是相当贵的。对这些资源进行优化是因为一个永恒的商业法则: -> 优化你最贵的资源Optimize your most expensive resource。 +> 优化你最贵的资源。 在过去,最贵的资源是计算机的运行时间。这就是导致计算机科学致力于研究不同算法的效率的原因。然而,这已经不再是正确的,因为现在硅芯片很便宜,确实很便宜。运行时间不再是你最贵的资源。公司最贵的资源现在是它的员工的时间。或者换句话说,就是你。把事情做完比快速地做事更加重要。实际上,这是相当的重要,我将把它再次放在这里,仿佛它是一个引用一样(对于那些只是粗略浏览的人): -> 把事情做完比快速地做事更加重要It’s more important to get stuff done than to make it go fast。 +> 把事情做完比快速地做事更加重要。 你可能会说:“我的公司在意速度,我开发一个 web 应用程序,那么所有的响应时间必须少于 x 毫秒。”或者,“我们失去了客户,因为他们认为我们的 app 运行太慢了。”我并不是想说速度一点也不重要,我只是想说速度不再是最重要的东西;它不再是你最贵的资源。 @@ -25,7 +25,7 @@ python 是慢,但是爷就喜欢它 当你在编程的背景下说 _速度_ 时,你通常意味着性能,也就是 CPU 周期。当你的 CEO 在编程的背景下说 _速度_ 时,他指的是业务速度,最重要的指标是产品上市的时间。基本上,你的产品/web 程序是多么的快并不重要。它是用什么语言写的也不重要。甚至它需要花费多少钱也不重要。在一天结束时,让你的公司存活下来或者死去的唯一事物就是产品上市时间。我不只是说创业公司的想法 -- 你开始赚钱需要花费多久,更多的是“从想法到客户手中”的时间期限。企业能够存活下来的唯一方法就是比你的竞争对手更快地创新。如果在你的产品上市之前,你的竞争对手已经提前上市了,那么你想出了多少好的主意也将不再重要。你必须第一个上市,或者至少能跟上。一但你放慢了脚步,你就输了。 -> 企业能够存活下来的唯一方法就是比你的竞争对手更快地创新The only way to survive in business is to innovate faster than your competitors。 +> 企业能够存活下来的唯一方法就是比你的竞争对手更快地创新。 #### 一个微服务的案例 @@ -46,7 +46,7 @@ python 是慢,但是爷就喜欢它 > 在高吞吐量的环境中使用解释性语言似乎是矛盾的,但是我们已经发现 CPU 时间几乎不是限制因素;语言的表达性是指,大多数程序是源程序,同时花费它们的大多数时间在 I/O 读写和本机运行时代码。而且,解释性语言无论是在语言层面的轻松实验还是在允许我们在很多机器上探索分布计算的方法都是很有帮助的, 再次强调: -> CPU 时间几乎不是限制因素the CPU time is rarely the limiting factor。 +> CPU 时间几乎不是限制因素。 ### 如果 CPU 时间是一个问题怎么办? @@ -79,12 +79,76 @@ python 是慢,但是爷就喜欢它 * * * -### 但是如何速度真的重要怎么办呢? +### 但是如果速度真的重要呢? + + ![](https://cdn-images-1.medium.com/max/600/0*bg31_URKZ7xzWy5I.jpg) + + 上述论点的语气可能会让人觉得优化与速度一点也不重要。但事实是,很多时候运行时性能真的很重要。一个例子是,你有一个web应用程序,其中有一个特定的端点需要用很长的时间来响应。你知道这个程序需要多快,并且知道程序需要改进多少。 + +在我们的例子中,发生了两件事: + +1. 我们注意到有一个端点执行缓慢。 +2. 我们承认它是缓慢,因为我们有一个可以衡量是否足够快的标准,而它要没达到那个标准。 + +我们不必在应用程序中微调优化所有内容,只需要让其中每一个都"足够快"。如果一个端点花费了几秒钟来响应,你的用户可能会注意到,但是,他们并不会注意到你将响应时间由35毫秒到25毫秒。"足够好"就是你需要做到的所有事情。_免责声明: 我应该说有一些应用程序,如实时投标程序,确实需要细微优化,每一毫秒都相当重要。但那只是例外,而不是规则。_ + +为了明白如何对端点进行优化,你的第一步将是配置代码,并尝试找出瓶颈在哪。毕竟: + +> 任何除了瓶颈之外的改进都是错觉。 --Gene Kim + +如果你的优化没有触及到瓶颈,你只是浪费你的时间,并没有解决实际问题。在你优化瓶颈之前,你不会得到任何重要的改进。如果你在不知道瓶颈是什么前尝试优化,那么你最终只会在部分代码中玩耍。在测量和确定瓶颈之前优化代码被称为“过早优化”。Donald Knuth经常被归咎于以下引语,但他声称他偷了别人的话: + +> 过早优化是万恶之源。 + +在谈到维护代码库时,来自Donald Knuth的更完整的引用是: + +> 在 97% 的时间里,我们应该忘记微不足道的效率:过早的优化是万恶之源。然而在关 +> 键的3%,我们不应该错过优化的机会。 ——Donald Knuth + +换句话说,他所说的是,在大多数时间你应该忘记对你的代码进行优化。它几乎总是足够好。在不是足够好的情况下,我们通常只需要触及3%的代码路径。你的端点快了几纳秒,比如因为你使用了if语句而不是函数,但这并不会使你赢得任何奖项, + +过早的优化包括调用某些更快的函数,或者甚至使用特定的数据结构,因为它通常更快。计算机科学认为,如果一个方法或者算法与另一个具有相同的渐近增长(或者Big-O),那么它们是等价的,即使在实践中要慢两倍。计算机是如此之快,算法随着数据/使用增加而造成的计算增长远远超过实际速度本身。换句话说,如果你有两个O(log n)的函数,但是一个要慢两倍,这实际上并不重要。随着数据规模的增大,它们都以同样的速度"慢下来"。这就是过早优化是万恶之源的原因;它浪费了我们的时间,几乎从来没有真正有助于我们的性能改进。 + +就Big-O而言,你可以认为你的程序在所有的语言里都是O(n),其中n是代码或者指令的行数。对于同样的指令,它们以同样的速率增长。对于渐进增长,一种语言的速度快慢并不重要,所有语言都是相同的。在这个逻辑下,你可以说,为你的应用程序选择一种语言仅仅是因为它的“快速”是过早优化的最终形式。你选择的东西据说是快速而不用测量,而不理解瓶颈将在哪里。 + +> 为您的应用选择语言只是因为它的“快速”是过早优化的最终形式。 + +* * * + + ![](https://cdn-images-1.medium.com/max/1000/0*6WaZOtaXLIo1Vy5H.png) + +### 优化Python + +我最喜欢Python的一点是,它可以让你一次优化一点点代码。假设你有一个Python的方法,你发现它是你的瓶颈。你对它优化过几次,可能遵循[这里][14]和[那里][15]的一些指导,现在你正处在这样的地步,你很肯定Python本身就是你的瓶颈。Python有调用C代码的能力,这意味着,你可以用C重写这个方法来减少性能问题。你可以一次重写一个这样的方法。这个过程允许你用任何可以编译为C兼容汇编程序的语言编写良好优化的瓶颈方法。这让你能够在大多数时间何用Python编写,只在必要的时候都使用较低级的语言来写代码。 + + +有一种叫做Cython的编程语言,它是Python的超集。它几乎是Python和C的合并,是一种渐进类型的语言。任何Python代码都是有新的Cython代码,Cython代码可以编译成C代码。使用Cython,你可以编写一个模块或者一个方法,并逐渐进步到越来越多的C类型和性能。你可以将C类型和Python的鸭子类型合并在一起。使用Cython,你可以获得只在瓶颈处进行优化和在其他所有地方不失去Python的美丽的完美组合。 + + ![](https://cdn-images-1.medium.com/max/600/0*LStEb38q3d2sOffq.jpg) + +星战前夜的一幅截图:用Python编写的space MMO游戏。 + +当您最终遇到性能问题的Python墙时,你不需要把你的整个代码库用另一种不同的语言来编写。你只需要用Cython重写几个函数几乎就能得到你所需要的性能。这就是[星战前夜][16]采取的策略。这是一个大型多玩家的电脑游戏,在整个堆栈中使用Python和Cython。它们通过优化C/Cython中的瓶颈来实现游戏级别的性能。如果这个策略对他们有用,那么它应该对任何人都有帮助。或者,还有其他方法来优化你的Python。例如,[PyPy][17]是一个Python的JIT实现,它通过使用PyPy交换CPython(默认实现)为长时间运行的应用程序提供重要的运行时改进(如web server)。 + + ![](https://cdn-images-1.medium.com/max/1000/0*mPc5j1btWBFz6YK7.jpg) + + 让我们回顾一下要点: + + * 优化你最贵的资源。那就是你,而不是计算机。 + * 选择一种语言/框架/架构来帮助你快速开发(比如Python)。不要仅仅因为某些技术的快而选择它们。 + * 当你遇到性能问题时,请找到瓶颈所在。 + * 你的瓶颈很可能不是CPU或者Python本身。 + * 如何Python成为你的瓶颈(你已经优化过你的算法),那么可以转向热门的Cython或者C。 + * 尽情享受可以快速做完事情的乐趣。 + +我希望你喜欢阅读这篇文章就像我喜欢写这篇文章一样。如果你想说谢谢,请为我点下赞。另外,如果某个时候你想和我讨论Python,你可以在twitter上艾特我(@nhumrich),或者你可以在[Python slack channel][18]找到我。 + -------------------------------------------------------------------------------- +作者简介:坚持采用持续交付的方法,并为之写了很多工具。同是还是一名Python黑客与技术逛热者,目前是一名devops工程师。 -via: https://hackernoon.com/yes-python-is-slow-and-i-dont-care-13763980b5a1 +via: https://medium.com/hacker-daily/yes-python-is-slow-and-i-dont-care-13763980b5a1 作者:[Nick Humrich ][a] 译者:[zhousiyu325](https://github.com/zhousiyu325)