python 文字是否保存在函数体内?
Are python literals saved inside function bodies?
我有一个函数需要在一个相当紧凑的循环内执行,因此它对性能很敏感。它是一种过滤功能,旨在节省更昂贵的工作。大多数功能只是针对静态列表的检查。
所以(去掉一些不相关的细节)我可以在这里做两件不同的事情:
def my_filter(arg):
SAFE_VALS = {
'a',
'b',
'f',
'i',
'm'
}
# the real list is much larger, but
# it is a static set like the above...
return arg in SAFE_VALS
或
# make this a module level constant
SAFE_VALS = {
'a',
'b',
'f',
'i',
'm'
}
def my_filter(arg):
return arg in SAFE_VALS
我知道 Python 必须查找更高一级的作用域才能找到模块级别的版本——但我不知道 my_filter
的编译版本是否有效地重新创建了这个每次函数为 运行 或文字被“烘焙”到函数 def 时设置。如果每次调用都分配一个新集合,感觉我最好使用模块级版本——如果不是,我不会通过将文字提升到函数范围之外来获得任何好处。
现在分析数据非常嘈杂,我看不出有什么明显区别。但是,如果该集合包含更多的长字符串,我会吗?或者这些形式之间现在有显着差异吗?
作为语言语义的问题,{'a', 'b', 'f', 'i', 'm'}
的意思是“用这些内容创建一个 new 集合”。语言语义允许为不可变类型重用现有对象,但集合是可变的。
作为实现细节,CPython 目前优化了形式为 x in {stuff}
的表达式,其中右侧是仅包含常量的集合表达式。在这种情况下,Python 将预先计算一个冻结集并将其保存在代码对象的 co_consts
中。将集合保存到变量会阻止优化。
为了保证不重新计算集合,独立于实现细节,您应该自己预先计算集合并将SAFE_VALS
保存为全局变量。
我有一个函数需要在一个相当紧凑的循环内执行,因此它对性能很敏感。它是一种过滤功能,旨在节省更昂贵的工作。大多数功能只是针对静态列表的检查。
所以(去掉一些不相关的细节)我可以在这里做两件不同的事情:
def my_filter(arg):
SAFE_VALS = {
'a',
'b',
'f',
'i',
'm'
}
# the real list is much larger, but
# it is a static set like the above...
return arg in SAFE_VALS
或
# make this a module level constant
SAFE_VALS = {
'a',
'b',
'f',
'i',
'm'
}
def my_filter(arg):
return arg in SAFE_VALS
我知道 Python 必须查找更高一级的作用域才能找到模块级别的版本——但我不知道 my_filter
的编译版本是否有效地重新创建了这个每次函数为 运行 或文字被“烘焙”到函数 def 时设置。如果每次调用都分配一个新集合,感觉我最好使用模块级版本——如果不是,我不会通过将文字提升到函数范围之外来获得任何好处。
现在分析数据非常嘈杂,我看不出有什么明显区别。但是,如果该集合包含更多的长字符串,我会吗?或者这些形式之间现在有显着差异吗?
作为语言语义的问题,{'a', 'b', 'f', 'i', 'm'}
的意思是“用这些内容创建一个 new 集合”。语言语义允许为不可变类型重用现有对象,但集合是可变的。
作为实现细节,CPython 目前优化了形式为 x in {stuff}
的表达式,其中右侧是仅包含常量的集合表达式。在这种情况下,Python 将预先计算一个冻结集并将其保存在代码对象的 co_consts
中。将集合保存到变量会阻止优化。
为了保证不重新计算集合,独立于实现细节,您应该自己预先计算集合并将SAFE_VALS
保存为全局变量。