- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如果我们用Python编写一个函数,其执行依赖于已知的外部变量,Python每次仍然会检查它
我是说
def fun():
return 1 if False else 5
每次调用此函数时都会重新检查此“False”
这可以通过简单的方式进行简单检查:
def pp(t, s):
print(s)
return t
def returner(t):
return t if pp(True, "YAY") else 0
list(map(returner,[1,2,3,4,5]))
将打印“YAY”5次
是否有一种方法可以“预编译”函数,以便每次调用函数时都不会检查此类条件,而仅在编译时才检查
也就是说,一种告诉编译器“这个表达式在编译时已知,找出并替换它。
添加是为了回复 @Cepner 的帖子:
你是对的,但还有第三者:执行速度。
在您的示例中:
X = 5
def fun():
return __precompute__(X * 5)
X = 7
我真的可以只写return 25
,但是如果该函数是在另一个函数内定义的,并且其定义取决于传递给发生此定义的函数的参数,该怎么办?我无法立即手写返回值,因为我不知道传入的参数,但定义函数知道。
在这种情况下,假设编译时参数是传递给父函数的参数,并且它永远不会再改变。
示例
def parent(parent_1, parent_2, parent_3, parent_4, long_array):
def child(x):
s = 0
if parent_1:
s += x**2
if parent_2:
s += x**x
if parent_3:
s += 2*x
if parent_4:
s += 74
return s
return sum(list(map(child, long_array)))
这样的话,这些参数不会改变,每次检查都会花很长时间,根本无法完成
在“快速语言”中,例如C++,在这种情况下,子函数在程序执行过程中绝对无法被优化。但我们处理的是 Python,其中程序可以在运行时更改自身,因此理论上可以在运行时进行此类子函数的优化和编译。
我的问题是,有没有技术手段可以在运行时对函数进行这样的优化和编译?
最佳答案
识别可以在像 Python 这样的动态语言中安全地减少的表达式总是有成本的。例如,
X = 5
def fun():
return X * 5
无法优化
def fun():
return 25
没有进行整个程序分析来验证 X
从未被分配过不同的值。 Python 本身没有指定任何此类优化,但各个实现可以自由地添加他们认为合适的优化。例如,CPython 会优化某些常量表达式并消除某些条件下的死代码。您可以使用 dis
模块查看为给定函数生成的字节代码。
>>> def fun(): return 5*5
...
>>> dis.dis(fun)
1 0 LOAD_CONST 1 (25)
2 RETURN_VALUE
或
>>> def fun():
... if False:
... return 1
... else:
... return 5
...
>>> dis.dis(fun)
5 0 LOAD_CONST 1 (5)
2 RETURN_VALUE
条件表达式没有类似地优化。
>>> def fun():
... return 1 if False else 5
...
>>> dis.dis(fun)
2 0 LOAD_CONST 1 (False)
2 POP_JUMP_IF_FALSE 8
4 LOAD_CONST 2 (1)
6 RETURN_VALUE
>> 8 LOAD_CONST 3 (5)
10 RETURN_VALUE
我怀疑这是因为优化器不想深入到表达式来识别死代码,而只是语句(存在于 AST 的更高级别)。您可以通过将 False
替换为可在编译时计算为 False
的表达式来停止优化,但优化器同样不会这样做。
>>> def fun():
... if 3 == 5:
... return 1
... else: return 5
...
>>> dis.dis(fun)
2 0 LOAD_CONST 1 (3)
2 LOAD_CONST 2 (5)
4 COMPARE_OP 2 (==)
6 POP_JUMP_IF_FALSE 12
3 8 LOAD_CONST 3 (1)
10 RETURN_VALUE
4 >> 12 LOAD_CONST 2 (5)
14 RETURN_VALUE
16 LOAD_CONST 0 (None)
18 RETURN_VALUE
好吧,自动识别可以安全简化的代码是很困难的;也许有一种方法可以标记要简化的代码。但即使这样的语法仍然需要验证优化是否安全。考虑上面的第一个例子;你可以说优化X * 5
是安全的,但是Python应该对以下内容做什么?
X = 5
def fun():
return __precompute__(X * 5)
X = 7
如果您预先计算 fun
,它将始终返回 25
,即使您在 fun
之前更改了 X
的值code> 曾经被调用过。这只会使 fun
的定义变得困惑,如果您的意图是这样的话,您可以首先编写 return 25
。请记住,代码生成器受可以做什么的限制,而不是您打算做什么。
考虑到此类标记的代码仍然必须进行安全性分析,是否真的值得将语法复杂化以获取比自动优化更有用的东西?
关于python - python中的"Precompile"函数,编译时计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75722116/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!