mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-02-25 00:50:15 +08:00
校对完毕 @zhousiyu325
校对完毕, 谢谢,文笔很流畅
This commit is contained in:
parent
4e88e59b45
commit
58d586eb12
@ -1,4 +1,4 @@
|
||||
python 是慢,但我并不关心
|
||||
python 是慢,但无须过度在意
|
||||
=====================================
|
||||
|
||||
### 对追求生产率而牺牲性能的怒吼
|
||||
@ -35,7 +35,7 @@ python 是慢,但我并不关心
|
||||
|
||||
微服务本来就很慢。微服务的主要概念是用网络调用来打破边界。这意味着你正在使用一个函数调用(几个 cpu 周期)并将它转变为一个网络调用。没有什么比这更影响性能了。和 CPU 相比较,网络调用真的很慢。但是这些大公司仍然选择使用微服务。我所知道的架构里面没有比微服务还要慢的了。微服务最大的弊端就是它的性能,但是最大的长处就是上市的时间。通过在较小的项目和代码库上建立团队,一个公司能够以更快的速度进行迭代和创新。这恰恰表明了,非常大的公司也很在意上市时间,而不仅仅只是只有创业公司。
|
||||
|
||||
#### CPU不是你的瓶颈
|
||||
#### CPU 不是你的瓶颈
|
||||
|
||||

|
||||
|
||||
@ -83,69 +83,70 @@ python 是慢,但我并不关心
|
||||
|
||||

|
||||
|
||||
上述论点的语气可能会让人觉得优化与速度一点也不重要。但事实是,很多时候运行时性能真的很重要。一个例子是,你有一个web应用程序,其中有一个特定的端点需要用很长的时间来响应。你知道这个程序需要多快,并且知道程序需要改进多少。
|
||||
上述论点的语气可能会让人觉得优化与速度一点也不重要。但事实是,很多时候运行时性能真的很重要。一个例子是,你有一个 web 应用程序,其中有一个特定的端点需要用很长的时间来响应。你知道这个程序需要多快,并且知道程序需要改进多少。
|
||||
|
||||
在我们的例子中,发生了两件事:
|
||||
|
||||
1. 我们注意到有一个端点执行缓慢。
|
||||
2. 我们承认它是缓慢,因为我们有一个可以衡量是否足够快的标准,而它要没达到那个标准。
|
||||
|
||||
我们不必在应用程序中微调优化所有内容,只需要让其中每一个都"足够快"。如果一个端点花费了几秒钟来响应,你的用户可能会注意到,但是,他们并不会注意到你将响应时间由35毫秒到25毫秒。"足够好"就是你需要做到的所有事情。_免责声明: 我应该说有一些应用程序,如实时投标程序,确实需要细微优化,每一毫秒都相当重要。但那只是例外,而不是规则。_
|
||||
我们不必在应用程序中微调优化所有内容,只需要让其中每一个都“足够快”。如果一个端点花费了几秒钟来响应,你的用户可能会注意到,但是,他们并不会注意到你将响应时间由 35 毫秒降低到 25 毫秒。“足够好”就是你需要做到的所有事情。_免责声明: 我应该说有**一些**应用程序,如实时投标程序,**确实**需要细微优化,每一毫秒都相当重要。但那只是例外,而不是规则。_
|
||||
|
||||
为了明白如何对端点进行优化,你的第一步将是配置代码,并尝试找出瓶颈在哪。毕竟:
|
||||
|
||||
> 任何除了瓶颈之外的改进都是错觉。 --Gene Kim
|
||||
|
||||
如果你的优化没有触及到瓶颈,你只是浪费你的时间,并没有解决实际问题。在你优化瓶颈之前,你不会得到任何重要的改进。如果你在不知道瓶颈是什么前尝试优化,那么你最终只会在部分代码中玩耍。在测量和确定瓶颈之前优化代码被称为“过早优化”。Donald Knuth经常被归咎于以下引语,但他声称他偷了别人的话:
|
||||
如果你的优化没有触及到瓶颈,你只是浪费你的时间,并没有解决实际问题。在你优化瓶颈之前,你不会得到任何重要的改进。如果你在不知道瓶颈是什么前就尝试优化,那么你最终只会在部分代码中玩耍。在测量和确定瓶颈之前优化代码被称为“过早优化”。人们常提及 Donald Knuth 说的话,但他声称实际是他偷了别人的话:
|
||||
|
||||
> 过早优化是万恶之源。
|
||||
> <ruby>过早优化是万恶之源<rt>Premature optimization is the root of all evil</rt></ruby>。
|
||||
|
||||
在谈到维护代码库时,来自Donald Knuth的更完整的引用是:
|
||||
在谈到维护代码库时,来自 Donald Knuth 的更完整的引用是:
|
||||
|
||||
> 在 97% 的时间里,我们应该忘记微不足道的效率:过早的优化是万恶之源。然而在关
|
||||
> 键的3%,我们不应该错过优化的机会。 ——Donald Knuth
|
||||
> 在 97% 的时间里,我们应该忘记微不足道的效率:**过早的优化是万恶之源**。然而在关
|
||||
> 键的 3%,我们不应该错过优化的机会。 ——Donald Knuth
|
||||
|
||||
换句话说,他所说的是,在大多数时间你应该忘记对你的代码进行优化。它几乎总是足够好。在不是足够好的情况下,我们通常只需要触及3%的代码路径。你的端点快了几纳秒,比如因为你使用了if语句而不是函数,但这并不会使你赢得任何奖项,
|
||||
换句话说,他所说的是,在大多数时间你应该忘记对你的代码进行优化。它几乎总是足够好。在不是足够好的情况下,我们通常只需要触及 3% 的代码路径。你的端点快了几纳秒,比如因为你使用了 if 语句而不是函数,但这并不会使你赢得任何奖项。
|
||||
|
||||
过早的优化包括调用某些更快的函数,或者甚至使用特定的数据结构,因为它通常更快。计算机科学认为,如果一个方法或者算法与另一个具有相同的渐近增长(或者Big-O),那么它们是等价的,即使在实践中要慢两倍。计算机是如此之快,算法随着数据/使用增加而造成的计算增长远远超过实际速度本身。换句话说,如果你有两个O(log n)的函数,但是一个要慢两倍,这实际上并不重要。随着数据规模的增大,它们都以同样的速度"慢下来"。这就是过早优化是万恶之源的原因;它浪费了我们的时间,几乎从来没有真正有助于我们的性能改进。
|
||||
过早的优化包括调用某些更快的函数,或者甚至使用特定的数据结构,因为它通常更快。计算机科学认为,如果一个方法或者算法与另一个具有相同的渐近增长(或者 Big-O),那么它们是等价的,即使在实践中要慢两倍。计算机是如此之快,算法随着数据/使用增加而造成的计算增长远远超过实际速度本身。换句话说,如果你有两个 O(log n) 的函数,但是一个要慢两倍,这实际上并不重要。随着数据规模的增大,它们都以同样的速度“慢下来”。这就是过早优化是万恶之源的原因;它浪费了我们的时间,几乎从来没有真正有助于我们的性能改进。
|
||||
|
||||
就Big-O而言,你可以认为你的程序在所有的语言里都是O(n),其中n是代码或者指令的行数。对于同样的指令,它们以同样的速率增长。对于渐进增长,一种语言的速度快慢并不重要,所有语言都是相同的。在这个逻辑下,你可以说,为你的应用程序选择一种语言仅仅是因为它的“快速”是过早优化的最终形式。你选择的东西据说是快速而不用测量,而不理解瓶颈将在哪里。
|
||||
就 Big-O 而言,你可以认为对你的程序,所有的语言都是 O(n),其中 n 是代码或者指令的行数。对于同样的指令,它们以同样的速率增长。对于渐进增长,一种语言的速度快慢并不重要,所有语言都是相同的。在这个逻辑下,你可以说,为你的应用程序选择一种语言仅仅是因为它的“快速”是过早优化的最终形式。你选择某些预期快速的东西,却没有测量,也不理解瓶颈将在哪里。
|
||||
|
||||
> 为您的应用选择语言只是因为它的“快速”是过早优化的最终形式。
|
||||
> 为您的应用选择语言只是因为它的“快速”,是过早优化的最终形式。
|
||||
|
||||
* * *
|
||||
|
||||

|
||||
|
||||
### 优化Python
|
||||
### 优化 Python
|
||||
|
||||
我最喜欢Python的一点是,它可以让你一次优化一点点代码。假设你有一个Python的方法,你发现它是你的瓶颈。你对它优化过几次,可能遵循[这里][14]和[那里][15]的一些指导,现在你正处在这样的地步,你很肯定Python本身就是你的瓶颈。Python有调用C代码的能力,这意味着,你可以用C重写这个方法来减少性能问题。你可以一次重写一个这样的方法。这个过程允许你用任何可以编译为C兼容汇编程序的语言编写良好优化的瓶颈方法。这让你能够在大多数时间何用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的美丽的完美组合。
|
||||
有一种叫做 Cython 的编程语言,它是 Python 的超集。它几乎是 Python 和 C 的合并,是一种渐进类型的语言。任何 Python 代码都是有新的 Cython 代码,Cython 代码可以编译成 C 代码。使用 Cython,你可以编写一个模块或者一个方法,并逐渐进步到越来越多的 C 类型和性能。你可以将 C 类型和 Python 的鸭子类型合并在一起。使用 Cython,你可以获得混合后的完美组合,只在瓶颈处进行优化,同时在其他所有地方不失去 Python 的美丽。
|
||||
|
||||

|
||||
|
||||
星战前夜的一幅截图:用Python编写的space MMO游戏。
|
||||
*星战前夜的一幅截图:用 Python 编写的 space MMO 游戏。*
|
||||
|
||||
当您最终遇到性能问题的Python墙时,你不需要把你的整个代码库用另一种不同的语言来编写。你只需要用Cython重写几个函数几乎就能得到你所需要的性能。这就是[星战前夜][16]采取的策略。这是一个大型多玩家的电脑游戏,在整个堆栈中使用Python和Cython。它们通过优化C/Cython中的瓶颈来实现游戏级别的性能。如果这个策略对他们有用,那么它应该对任何人都有帮助。或者,还有其他方法来优化你的Python。例如,[PyPy][17]是一个Python的JIT实现,它通过使用PyPy交换CPython(默认实现)为长时间运行的应用程序提供重要的运行时改进(如web server)。
|
||||
当您最终遇到性能问题的 Python 墙时,你不需要把你的整个代码库用另一种不同的语言来编写。你只需要用 Cython 重写几个函数,几乎就能得到你所需要的性能。这就是[星战前夜][16]采取的策略。这是一个大型多玩家的电脑游戏,在整个堆栈中使用 Python 和 Cython。它们通过优化 C/Cython 中的瓶颈来实现游戏级别的性能。如果这个策略对他们有用,那么它应该对任何人都有帮助。或者,还有其他方法来优化你的 Python。例如,[PyPy][17] 是一个 Python 的 JIT 实现,它通过使用 PyPy 交换 CPython(默认实现),为长时间运行的应用程序提供重要的运行时改进(如 web server)。
|
||||
|
||||

|
||||
|
||||
让我们回顾一下要点:
|
||||
|
||||
* 优化你最贵的资源。那就是你,而不是计算机。
|
||||
* 选择一种语言/框架/架构来帮助你快速开发(比如Python)。不要仅仅因为某些技术的快而选择它们。
|
||||
* 选择一种语言/框架/架构来帮助你快速开发(比如 Python)。不要仅仅因为某些技术的快而选择它们。
|
||||
* 当你遇到性能问题时,请找到瓶颈所在。
|
||||
* 你的瓶颈很可能不是CPU或者Python本身。
|
||||
* 如何Python成为你的瓶颈(你已经优化过你的算法),那么可以转向热门的Cython或者C。
|
||||
* 你的瓶颈很可能不是 CPU 或者 Python 本身。
|
||||
* 如果 Python 成为你的瓶颈(你已经优化过你的算法),那么可以转向热门的 Cython 或者 C。
|
||||
* 尽情享受可以快速做完事情的乐趣。
|
||||
|
||||
我希望你喜欢阅读这篇文章就像我喜欢写这篇文章一样。如果你想说谢谢,请为我点下赞。另外,如果某个时候你想和我讨论Python,你可以在twitter上艾特我(@nhumrich),或者你可以在[Python slack channel][18]找到我。
|
||||
我希望你喜欢阅读这篇文章,就像我喜欢写这篇文章一样。如果你想说谢谢,请为我点下赞。另外,如果某个时候你想和我讨论 Python,你可以在 twitter 上艾特我(@nhumrich),或者你可以在 [Python slack channel][18] 找到我。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
作者简介:坚持采用持续交付的方法,并为之写了很多工具。同是还是一名Python黑客与技术逛热者,目前是一名devops工程师。
|
||||
作者简介:
|
||||
Nick Humrich -- 坚持采用持续交付的方法,并为之写了很多工具。同是还是一名 Python 黑客与技术狂热者,目前是一名 devops 工程师。
|
||||
|
||||
|
||||
via: https://medium.com/hacker-daily/yes-python-is-slow-and-i-dont-care-13763980b5a1
|
||||
|
Loading…
Reference in New Issue
Block a user