最近我一直在修改一些旧的python代码,它们本质上是代数循环,以便让它们执行得更快,通常是通过消除一些不必要的操作。通常,将列表中的条目值从0(作为python float,我认为默认为double)更改为相同的值,这显然不是必需的。或者,检查一个浮点数是否等于某个东西,当它必须是那个东西时,因为前面的“if”如果不是就会触发,或者其他一些无关的操作。这让我想知道什么会更多地保留我的电池,因为我在总线上做了一些我无法插入笔记本电脑的编码。
例如,预计以下两项操作中哪一项使用的电池电量较少?
if b != 0: #b was assigned previously, and I know it is zero already
b = 0
或:
b = 0
第一个检查b是否为0,它是,因此它不会执行下一部分。第二个只是将b分配给零而不用费心去检查。我相信第一个更节省时间,因为你不必改变记忆中的任何东西。这是正确的,如果是这样,它还会更节能吗? “更有效率”是否总意味着“更节能”?
答案 0 :(得分:1)
我建议Chandler Carruth看这个演讲:"Efficiency with Algorithms, Performance with Data Structures" 他阐述了"节能指令"在4m 49s的视频中。我同意他的看法,想一想特定代码耗费多少瓦特是没用的。正如他所说的那样
问:"如何节省电池寿命?"
答:"完成破坏程序"。
另外,在Python中你没有低级别的控制来考虑像这样的低级问题。使用适当的数据结构和算法,并祈祷Python解释器将为您提供优化的字节码。
答案 1 :(得分:0)
每个简单的数学运算都使用相同的功率(如电池电量)吗?
没有。计算两个数字的加法不同于2000万像素照片的傅里叶变换。
我相信第一个更节省时间,因为你不必改变记忆中的任何东西。这是正确的,如果是这样,它还会更节能吗? “更有效率”是否总意味着“更节能”?
是。你的直觉是对的,但这些都是非常简单的例子。如果你深入挖掘,你将进入一个非常难以理解的奇怪优化的未知领域(例如,看到这个问题:Times two faster than bit shift?)
答案 2 :(得分:0)
通常,您的代码使用系统资源越多,这些资源将使用的功率越大。但是,根据时间或大小限制优化代码更有用,而不是考虑功耗的高级代码。
这样做的一种方法是Big O表示法。实质上,Big O表示法是一种比较算法的大小和/或运行时复杂性的方法。 https://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/
处于最低级别的计算机是大量的晶体管,需要电力来改变和维持其状态。 预计任何一行python代码将会消耗多少功率是非常困难的。
答案 3 :(得分:0)
我曾经有这样的问题。有时仍然这样做。以下是我希望有人早些时候告诉我的答案。
通常情况下,如果您的计算机工作量较少,那么它是正确的,它会耗电更少。
但是我们必须非常小心地确定哪些逻辑操作涉及更多工作,哪些涉及更少的工作 - 在这种情况下:
if
以及任何其他条件执行费用。从某种角度来看:您已经在询问哪些Python代码会花费更多 drop 水,但实际上在Python中,每次操作都会花费桶并且您的整个Python程序使用河,您的计算机整体使用海洋。
不要将这些答案应用于Python 。首先阅读其余的答案,因为Python和CPU之间有如此多的间接性,如果你不考虑这一点,你就会误导他们如何联系他们。
我相信第一个更节省时间,因为你不必改变记忆中的任何东西。
作为一般规则,读取内存与写入内存一样慢,或者甚至更慢,具体取决于您的计算机正在做什么。为了进一步阅读,您将要了解CPU内存高速缓存级别,内存访问时间以及无序执行和数据依赖性如何影响现代CPU架构。
作为一般规则,语言中的if
语句本身是一项可以具有不可忽略的成本的操作。为了进一步阅读,您应该了解CPU流水线操作如何与分支预测和分支处罚相关。另请参阅如何在典型的CPU指令集中实现if
语句。
"更节省时间"总是暗示"更节能"?
作为一般规则,提高工作效率(减少工作量 - 减少机器指令)意味着更节能,因为现代硬件< / em>(这不总是这样)当你的硬件没有做任何事情时,你的硬件会耗电少。
你应该注意&#34;更多时间效率&#34;但是,因为现代硬件并不总是在相同的时间内执行相同数量的工作:为了进一步阅读,您将要研究CPU频率扩展,ARM的big.LITTLE架构,和#34;竞赛到空闲&#34;以概念为出发点。
你的问题是关于Python的,所以认识到Python的x != 0
,if
和x = 0
不能直接映射到简单的操作是非常重要的。 CPU 。
为了进一步阅读,特别是如果您熟悉C,我建议您仔细研究如何实现Python。有许多实现 - 主要的是CPython,它是一个C程序,它读取和解释Python源代码,将其转换为Python&#34;字节码&#34;然后在运行时逐个解释该字节码。
作为基准,如果你正在使用Python,那么任何一个&#34;简单&#34;操作实际上是CPU操作的 lot ,因为Python解释器中的每一步都是多CPU操作,但哪些成本更高可能会令人惊讶。
让我们分解我们示例中使用的三个(我主要是从用C编写的主要Python实现的角度来描述这个,称为&#34; CPython&#34;,我是最熟悉的,但一般这个解释大致适用于所有这些,尽管有些人能够优化某些步骤):
x != 0
它看起来像一个简单的操作,如果这是C并且x
是int
它只是一个机器指令 - 但Python允许运算符重载,所以首先Python必须: / p>
x
(至少一次内存读取,但可能涉及Python内部的一个或多个hashmap查找,这是许多机器操作),x
的类型(更多内存读取),x
和0
值的Python对象来调用该函数(这也不是&#34; free&#34; - 查找函数调用A B 我对此有更多了解。)所有这些以及 more 必须由CPU 完成,即使 x
是Python int
或float
映射密切关注CPU的本机数值数据类型。
x = 0
在Python中,赋值实际上便宜得多(虽然仍然不是微不足道):它只需要达到上面的第1步,因为一旦它知道&#34;其中&#34; x
是,它只能用指向0
的Python对象的指针覆盖该指针。
if
抽象地说,Python if
语句必须能够处理&#34; truthy&#34;和&#34; falsey&#34;值,在最天真的实现中将涉及运行更多的CPU指令来根据Python的真实和错误的语义来评估条件的结果。
不同的Python实现会使用不同的长度来使Python操作更接近尽可能少的CPU操作。例如,优化JIT(即时)编译器可能会注意到,在数组的某个循环内,数组的所有元素都是本机整数,实际上将if x != 0
和x = 0
部分缩减为各自的最小的机器指令,但这只发生在非常特殊的情况下,当优化逻辑可以证明它可以安全地绕过它通常需要做的很多行为。
这里的最重要的事情是这样的:像Python这样的高级语言已从硬件中删除了&#34;简单&#34;操作通常很复杂&#34;在幕后&#34;。
如果我错了,请纠正我,但我怀疑你实际想到的用例是这样的:
if x != 0:
# some code
x = 0
VS。这样:
if x != 0:
# some code
x = 0
在这种情况下,第一个选项 优于第二个选项,因为已经支付了<{1}} 的费用
对我而言,最艰难的突破是不再试图理解我头脑中的个别指示,而是切换到查看工作原理和测量真实系统。
查看工作原理将教会您如何进行优化,但测量会向您显示 where to优化
这个问题非常适合探索前者,但是为了减少笔记本电脑的耗电量,你会从后者中受益更多。