【问题标题】:Is there a clean way to check a variable inside a loop on the first iteration only or before its execution?是否有一种干净的方法可以仅在第一次迭代时或在执行之前检查循环内的变量?
【发布时间】:2021-03-07 02:49:48
【问题描述】:

我的代码是用 Python 编写的,但这个问题适用于任何编程语言。

基本上,我有一个类似这样结构的循环:

while True:
    if visual:
        print("Something meaningful")
    function1()
    function2()

可视变量由用户在使用 CLI 参数调用脚本时确定,它是一个布尔值。基本上,如果设置为 True,用户会获得视觉反馈,如果设置为 False,则不会。

问题在于循环会在每次迭代时检查该变量,从而稍微减慢执行速度。

因此,我想知道是否有一种干净的方法可以避免在每次迭代时检查“visual”是否为真,以某种方式告诉程序仅在第一次迭代时检查该变量,因为变量不能在中间更改-执行。

我想过做这样的事情:

if visual:       
    while True:
        print("Something meaningful")
        function1()
        function2()
else:
    while True:
        function1()
        function2()

它有效,但它似乎根本不是一个好的做法。

解决这个问题最干净的方法是什么?

【问题讨论】:

  • “稍微减慢执行速度”,当您已经在使用 python 时,检查静态布尔值并不是优化的重点。
  • @OlvinR​​oght 我同意,我实际上并不想优化它,我实际上只是好奇。如果您考虑一下,检查一个布尔值在执行时间方面毫无意义,但如果我让这个循环运行一周或一个月,我确信每次迭代检查一个变量加起来就是可以被认为是有意义的东西。
  • 如果 function1() 和 function2() 不是微不足道的,布尔检查将可以忽略不计。您可以使用相同的参数内联函数以减少子程序跳转的开销。

标签: python algorithm loops if-statement while-loop


【解决方案1】:

我首先将while 循环中的函数分组到一个新函数中。然后在循环之前我们检查visual 是否为真,如果是,那么我们装饰 functions() 用一个包装器

def functions():
    function1()
    function2()

def _visual_decorator(func):
    def _wrapper(*args, **kwargs):
        print("Something meaningful")
        return func(*args, **kwargs)
    return _wrapper

if visual:
    functions = _visual_decorator(functions)

while True:
    functions()

Full working example

【讨论】:

  • 嘿,这行得通!正是我正在寻找的答案类型。但是,我以前听说过装饰器,但从未真正研究过它们。您介意详细说明 _visual_decorator 函数的作用吗?提前致谢!
  • 很高兴我能帮上忙!我推荐this answerthis video 来学习包装器和装饰器。 _visual_decorator 将任何 callable 作为参数并返回另一个具有相同 signaturecallable。返回的callable,一旦被调用,在我们的例子中将调用print 函数,然后返回第一个给定callable的结果。
【解决方案2】:

您正在使用branchless programming 方法。您应该转换您的循环,使其不使用第一个分支if
要做到这一点通常取决于您使用的语言及其提供的功能。
例如,在 Python 中,可以将两个函数放在一个 map 中,并根据变量 value 使用其中一个:

functions = {True: print, False: lambda x: x}
value = False
func = functions[value]
while True:
  func("Something useful")
  function1()
  function2()

这是一种方法,并不是唯一的方法。其他语言有自己的方式来实现相同的目标。
请注意,虽然在 Python 中这可能没有太大区别,但一般而言,无分支编程可能会优化您的程序运行时间,有时会优化几个数量级!

【讨论】:

  • 嘿,谢谢你的回答,我从来没有听说过“无分支编程”。您是说在您提供的代码中,functions[value]("Something useful") 行只运行一次?
  • 不,它将在每次迭代中运行。但是你可以把它拿出来。我会更新答案。
  • 无分支编程是一种编程方法,您可以避免使用像 ifswitch 语句这样的分支,因为它们会破坏处理器中的管道
  • 只会运行一次的内容是您在映射中作为键 True 的值,在本例中为 print 函数。
猜你喜欢
  • 1970-01-01
  • 2020-07-02
  • 1970-01-01
  • 2020-03-18
  • 2013-01-04
  • 2018-07-07
  • 1970-01-01
  • 2019-03-15
  • 2011-09-07
相关资源
最近更新 更多