This blog mentions three things about python Loop optimization details , If there are other optimization schemes , Welcome to share your message ~QWQ
<> Rational use of generators （generator） and yield
Before we talk about this link , Let's take a look at what generators are and what they are yield
Understand yiled You also need to understand the generator , Instead, understand the generator , First, you need to understand iterators .
All you can use in for...in... Statements are iteratable : such as lists,strings,files
… Because these iteratable objects can be read freely, they are very easy to use , But you have to put their values in memory , They consume too much memory when they have many values .
Generator is also a kind of iterator , But you can only iterate them once . The reason is simple , Because they're not all in memory , They are only generated in memory when they are to be called , Here are two examples ：
>>> mygenerator = (x*x for x in range(3)) >>> for i in mygenerator: ...
print(i) ... 0 1 4 >>>
>>> listTest = [x*x for x in range(3)] >>> for i in listTest: ... print(i) ...
0 1 4
>>> print(listTest) [0, 1, 4] >>> print(mygenerator) <generator object <genexpr
> at 0x000001FAB703DE60>
The difference between a generator and an iterator is that () replace , And you can't use it for i in mygenerator
Calling the generator a second time : First calculate 0, And then it's lost in memory 0 To calculate 1, Until the calculation is finished 4.
Yield Usage and keywords of return almost , The following function will return a generator :
>>> def createGenerator(): ... mylist = range(3) ... for i in mylist: ... yield
i*i ... >>> mygenerator = createGenerator() >>> print(mygenerator) <generator
object createGenerator at 0x000001FAB703DE60> >>>
Understand Yield You have to understand that when you call a function , The code in the function is not running . Function returns only the generator object , That's where it's most subtle .
Here are two examples ：
1, Only separately generated generator And list object
import time import sys t1 = time.time() arange = (i for i in range(2000000))
print("brange size:") print(sys.getsizeof(arange)) t2 = time.time() print(
"arange time:") print(t2-t1) t3 = time.time() brange = [i for i in range(2000000
)] print("brange size:") print(sys.getsizeof(brange)) t4 = time.time() print(
"brange time:") print(t4-t3) # brange size: # 88 # arange time: # 0.0 # brange
size: # 17632632 # brange time: # 0.12857437133789062
use () You get one generator object , The memory space required is independent of the size of the list , So it will be more efficient . For the principle, see the generator principle section above .
2, Supply for Recycling
import time t1 = time.time() arange = (i for i in range(20000000)) for x in
arange: pass t2 = time.time() print("arange time:") print(t2-t1) t3 = time.time(
) brange = [i for i in range(20000000)] for x in brange: pass t4 = time.time()
print("brange time:") print(t4-t3) # arange time: # 1.7372145652770996 # brange
time: # 1.8086597919464111
Although it's not fast , But don't forget , In the case of better time , generator generator The memory space occupation is even more complete explosion list, So , The loop uses the generator as much as possible !!!!
<> Position of optimization cycle
There is no need to say or explain this , Don't put what you can do outside the loop , For example, the following optimization can be twice as fast ：
import time test = "123" length_test = len(test) t1 = time.time() arange = (i
for i in range(4000000)) for x in arange: ap = length_test t2 = time.time()
print("arange time:") print(t2-t1) t3 = time.time() brange = (i for i in range(
4000000)) for x in brange: bp = len(test) t4 = time.time() print("brange time:")
print(t4-t3) # arange time: # 0.460693359375 # brange time: # 0.8602120876312256
<>while 1 than while True Faster
2333, You may not believe that , But look at an example ：
import time def while_1(): t1 = time.time() n = 100000000 while 1: n -= 1 if n
<= 0: break t2 = time.time() print("while1 time:") print(t2-t1) def while_true()
: t3 = time.time() n = 100000000 while True: n -= 1 if n <= 0: break t4 = time.
time() print("while_true time:") print(t4-t3) if __name__ == '__main__': while_1
() while_true() # while1 time: # 5.369367837905884 # while_true time: #
As for the principle ：
True Is a global variable , Not keywords