3

My code is in Python, but this question goes for any programming language.

Basically, I have a loop that has a structure similar to this:

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

The visual variable is determined by the user when he calls the script with CLI arguments, its a boolean. Basically, if set to True, the user gets visual feedback, if False, he doesn't.

The problem is that the loop is going to check that variable on every iteration, slowing down the execution slightly.

I therefore wondered if there is a clean way to avoid having to check if "visual" is True on every iteration, to somehow tell the program to check that variable only on the first iteration, since the variable can't change mid-execution.

I thought of doing something like this :

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

It works, but it doesn't seem like good practice at all.

What is the cleanest way to solve this problem ?

Shiverz
  • 663
  • 1
  • 8
  • 23
  • 2
    *"slowing down the execution slightly"*, one check of static boolean value is not the point of optimization when you're already using python. – Olvin Roght Nov 24 '20 at 10:28
  • Related answer https://stackoverflow.com/questions/34572259/check-statement-for-a-loop-only-once – AverageHomosapien Nov 24 '20 at 10:29
  • 2
    @OlvinRoght I agree, I'm not actually looking to optimize this, I'm actually just curious. And if you think about it, checking one boolean is meaningless in terms of execution time, but if I let this loop run for a week, or a month, I'm sure the fact that that one variable being checked every iteration adds up to something that could be considered meaningful. – Shiverz Nov 24 '20 at 10:32
  • if function1() and function2() are not trivial, the boolean-check will be negligible. You could with the same argument inline the functions to reduce overhead of subroutine jumps. – MrSmith42 Nov 24 '20 at 10:41

2 Answers2

2

I would begin with grouping the functions from the while loop into a new function. Then before the loop we check if visual is True, if it is then we decorate functions() with a wrapper.

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

Mandera
  • 2,647
  • 3
  • 21
  • 26
  • 1
    Hey, yeah that works ! Exactly the type of answer I was looking for. However, I've heard of decorators before, but never actually studied them. Would you mind elaborating a little more on what the _visual_decorator function does? Thanks in advance ! – Shiverz Nov 24 '20 at 10:47
  • 1
    Glad I could help! I recommend [this answer](https://stackoverflow.com/questions/739654/how-to-make-a-chain-of-function-decorators/1594484#1594484) or [this video](https://www.youtube.com/watch?v=FsAPt_9Bf3U&t) to learn wrappers and decorators. `_visual_decorator` takes any _callable_ as an argument and returns another _callable_ with the same _signature_. The returned _callable_, once called, will in our case call the `print` function and then return the result of the first given _callable_. – Mandera Nov 24 '20 at 10:55
1

You're after a branchless programming approach. You should transform your loop so that it doesn't use the first branching if.
To do that generally depends on the language you're using and the features that it provides.
For example, in Python, you could put two functions in a map and use one of them according to the variable value:

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

This is one way to do it, and it is not the only way. Other languages have their own way to achieve the same thing.
Note that while in Python this might not give much difference, brancheless programming in general could potentially optimize your programs running time, sometimes by orders of magnitude!

Maaddy
  • 618
  • 5
  • 13
  • 1
    Hey, thanks for your answer, I've never heard of "branchless programming". You're saying that in the code you provided, the ```functions[value]("Something useful")``` line is ran only once? – Shiverz Nov 24 '20 at 10:55
  • 1
    No, it will run in every iteration. you could take it out however. I'll update the answer. – Maaddy Nov 24 '20 at 10:56
  • 1
    Branchless programming is a programming approach where you avoid using branching like `if` or `switch` statements because they wipeout the pipeline in the processor – Maaddy Nov 24 '20 at 10:58
  • 1
    What will be ran only once is whatever you put in the map as a value for the key `True`, in this case the `print` function. – Maaddy Nov 24 '20 at 11:02