-2

For example, I need this variable, which is a list of prime numbers. If I put it inside a function (that runs over 5000 times) the overall runtime is slower (3 - 4 seconds). If I use global instead, the script runs in less than 1 second (everyone says using global is bad though). What happens? I'm new to Python sorry!

primes = sorted([x for x in range(1, 10000) if is_prime(x)])
sickleox2
  • 35
  • 6
  • 3
    Your function does whatever you tell it to, each time you call it - if you tell it to make a list of prime numbers then that's what it does. – kaya3 Apr 08 '21 at 16:01
  • 1
    You could determine the list in the function that calls the function (that runs over 5000 times), then pass it in. – Amiga500 Apr 08 '21 at 16:02
  • @Amiga500: the outer one (caller) runs just once, presumably – Sergio Tulentsev Apr 08 '21 at 16:03
  • 2
    As a side note, there are much more efficient ways to generate all primes below 10000 than testing all numbers below 10000. See https://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n – Thierry Lathuille Apr 08 '21 at 16:04
  • @Sergio - I'd think we could assume at some point there is a level where its ran just once, even if that's right up in main(). But obviously passing from main() through several tiers to get to foo() could be a right bollox. Hence my hack answer I've put up. Not great practice, but useful for digging yourself out of a hole. – Amiga500 Apr 08 '21 at 16:12
  • 1
    @Amiga500 my comment was to clarify the original wording of your comment. It seemed ambiguous (to me, at least) – Sergio Tulentsev Apr 08 '21 at 16:14
  • Your not wrong - it was ambiguous! – Amiga500 Apr 08 '21 at 16:23

1 Answers1

0

Globals are bad. But sometimes they are a far simpler and more expedient solution than the alternative.

As a guard against inadvertent changes to globals, this is what I've been using for some time.

I'd make a separate .py, for instance myGlobalVariables.py and within it I'd have code like:

def setGlobalPrimes(primesIn):
    global globalPrimes
    globalPrimes = primesIn

Then, from within my main code, I'd

import myGlobalVariables

def foo():  #foo that runs 5000 times
    primes = myGlobalVariables.globalPrimes

    #calcs & stuff here

    return answers


if __name__ == "__main__":
    
    #prime all globals
    myGlobalVariables.setGlobalPrimes(sorted([x for x in range(1, 10000) if is_prime(x)]))
    

    #Then whatever you have in your code (obviously below is just me being silly)
    for i in range(0, 5000):            
        foo()

Basically, it makes the chances of you inadvertently updating/overwriting a global much harder. You can of course do it by:

myGlobalVariables.globalPrimes = [blah blah]

It stops you doing so many re-calcs, thus speeding up your code a bit.

Amiga500
  • 1,258
  • 1
  • 6
  • 11