Bottom Page

• 0 Vote(s) - 0 Average
• 1
• 2
• 3
• 4
• 5
 how good is the optimization? Skaperen So-and-so of the Yard Posts: 2,065 Threads: 608 Joined: Sep 2016 Reputation: 7 Likes received: 58 #1 Aug-09-2018, 04:54 AM how good is the optimization in Python? in this code will it cache the value from `s[n]` or will it fetch it twice? ``` if s[n]<128 or s[n]>191: return -2```or should i code this? ``` x = s[n] if x<128 or x>191: return -2```for best performance. What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American. Gribouillis Posts: 925 Threads: 5 Joined: Jan 2018 Reputation: 82 Likes received: 216 #2 Aug-09-2018, 05:52 AM I would use ```if not (128 <= s[n] <= 191): return -2 ```but I'm not sure it is better at execution time. The timeit module should answer this question. It's also a good idea to look at the bytecode. Skaperen and micseydel like this post DeaD_EyE Verb Conjugator Posts: 567 Threads: 4 Joined: May 2017 Reputation: 41 Likes received: 128 #3 Aug-09-2018, 07:16 AM Use dis to disassemble a function: ```import dis def func1(s, n): if s[n] < 128 or s[n] > 191: return -2 def func2(s, n): x = s[n] if x < 128 or x > 191: return -2 print('func1:') print(dis.dis(func1)) print('\nfunc2:') print(dis.dis(func2)) `````````Output: func1: 5 0 LOAD_FAST 0 (s) 2 LOAD_FAST 1 (n) 4 BINARY_SUBSCR 6 LOAD_CONST 1 (128) 8 COMPARE_OP 0 (<) 10 POP_JUMP_IF_TRUE 24 12 LOAD_FAST 0 (s) 14 LOAD_FAST 1 (n) 16 BINARY_SUBSCR 18 LOAD_CONST 2 (191) 20 COMPARE_OP 4 (>) 22 POP_JUMP_IF_FALSE 28 6 >> 24 LOAD_CONST 3 (-2) 26 RETURN_VALUE >> 28 LOAD_CONST 0 (None) 30 RETURN_VALUE None func2: 9 0 LOAD_FAST 0 (s) 2 LOAD_FAST 1 (n) 4 BINARY_SUBSCR 6 STORE_FAST 2 (x) 10 8 LOAD_FAST 2 (x) 10 LOAD_CONST 1 (128) 12 COMPARE_OP 0 (<) 14 POP_JUMP_IF_TRUE 24 16 LOAD_FAST 2 (x) 18 LOAD_CONST 2 (191) 20 COMPARE_OP 4 (>) 22 POP_JUMP_IF_FALSE 28 11 >> 24 LOAD_CONST 3 (-2) 26 RETURN_VALUE >> 28 LOAD_CONST 0 (None) 30 RETURN_VALUE None ``````In func1 you see LOAD_FAST s and n two times. In func2 there is only one time access to s and n. Usually what time costs are lookups to nonlocal and global names. Function and Method calls has been improved with Python 3.6 and 3.7. When you want to do micro-optimization, you'll benefit if you first assign all global names, to local names. ```import timeit import math def foo1(y): for i in range(1_000_000): yield math.sqrt(i) ** y def foo2(y): sqrt = math.sqrt for i in range(1_000_000): yield sqrt(i) ** y run1 = timeit.timeit('list(foo1(10))', globals=globals(), number=50) run2 = timeit.timeit('list(foo2(10))', globals=globals(), number=50) print(f'Function with global lookup: {run1:.2f} s\nFunction with local lookup: {run2:.2f} s') `````````Output: Function with global lookup: 12.97 s Function with local lookup: 9.79 s ``````Test it with the timeit module. Turn your power savings off, maybe you should also deactivate your turbo boost of your cpu, if your cpu supports it. I my case the cpu frequency is not fixed, so the test results are not always the same. Gribouillis and Larz60+ like this post My code examples are always for Python 3.x. All humans together. We don't need politicians! Gribouillis Posts: 925 Threads: 5 Joined: Jan 2018 Reputation: 82 Likes received: 216 #4 Aug-09-2018, 03:18 PM In this version, there are only two LOAD_FAST and no STORE_FAST ```>>> def func3(s, n): ... if not (128 <= s[n] <= 191): ... return -2 ... >>> import dis >>> dis.dis(func3) 2 0 LOAD_CONST 1 (128) 3 LOAD_FAST 0 (s) 6 LOAD_FAST 1 (n) 9 BINARY_SUBSCR 10 DUP_TOP 11 ROT_THREE 12 COMPARE_OP 1 (<=) 15 JUMP_IF_FALSE_OR_POP 27 18 LOAD_CONST 2 (191) 21 COMPARE_OP 1 (<=) 24 JUMP_FORWARD 2 (to 29) >> 27 ROT_TWO 28 POP_TOP >> 29 POP_JUMP_IF_TRUE 36 3 32 LOAD_CONST 4 (-2) 35 RETURN_VALUE >> 36 LOAD_CONST 0 (None) 39 RETURN_VALUE ``` nilamo Last Thursdayist Posts: 2,627 Threads: 67 Joined: Sep 2016 Reputation: 99 Likes received: 582 #5 Aug-09-2018, 06:14 PM (Aug-09-2018, 04:54 AM)Skaperen Wrote: how good is the optimization in Python? in this code will it cache the value from `s[n]` or will it fetch it twice? ``` if s[n]<128 or s[n]>191: return -2```or should i code this? ``` x = s[n] if x<128 or x>191: return -2```for best performance. I'm not sure this is an optimization issue. `s[n]` could have a different value every time it's accessed, so it'd HAVE to be accessed twice. This is easy enough to test, even if you don't want to dig into the `dis` module:```>>> class foo: ... def __getitem__(self, index): ... print("indexed!") ... return index ** 2 ... >>> x = foo() >>> x[4] indexed! 16 >>> if x[4] > 10 and x[4] < 50: ... print("match") ... indexed! indexed! match``` micseydel Knight Who Says Ni Posts: 1,544 Threads: 30 Joined: Sep 2016 Reputation: 33 Likes received: 448 #6 Aug-09-2018, 08:57 PM Note that these analyses are Python distribution-specific. IronPython, Jython and PyPy (especially PyPy) may perform differently (it wouldn't surprise me if PyPy detected here that there isn't a change, and optimized). CPython does no JIT'ing, so far as I know. Skaperen So-and-so of the Yard Posts: 2,065 Threads: 608 Joined: Sep 2016 Reputation: 7 Likes received: 58 #7 Aug-10-2018, 12:23 AM (This post was last modified: Aug-10-2018, 12:50 AM by Skaperen.) i like Gribouillis' solution to change the expression to have one expression for the in-between test. when i first saw that Python could do it that way, i had dismissed it in my mind as "i'm never going to do that" and for the reason that i considered it a "noobie feature". but this case shows a justification for it. it would be even more so if it were a big complex expression. i'm going to have to look into module dis. i have't, yet. what i would like to get is the disassembly written to a file, and run it interpreted. is that what .pyc and .pyo files are, in the binary form? if so, can the python engine make the .pyc file from it? i've long wanted to have an assembly-like language with namespace-like means to store variables, for the purpose of getting students more used to this kind of programming before they have get used to memory allocation aspects. fyi, i once did make an isbetween(a,b,c) macro in C that would make sure the expression to be tested as between two other expression was one chunk of code. i also did that in 370 assembler macro language. What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American. Gribouillis Posts: 925 Threads: 5 Joined: Jan 2018 Reputation: 82 Likes received: 216 #8 Aug-10-2018, 06:00 PM (This post was last modified: Aug-10-2018, 06:01 PM by Gribouillis. Edited 1 time in total.) (Aug-10-2018, 12:23 AM)Skaperen Wrote: if so, can the python engine make the .pyc file from it? You could perhaps use a module such as BytecodeAssembler for this (at least for python 2) « Next Oldest | Next Newest »

Top Page

 Possibly Related Threads... Thread Author Replies Views Last Post Is this a good way to become a Programmer? Urgent advice needed plz! MoTechie 1 139 Sep-15-2018, 10:48 PM Last Post: Larz60+ Why isn’t there any good hacking books written in Python 3 Takeshio 8 311 Aug-26-2018, 09:19 PM Last Post: Larz60+ Need Suggestion for a Good Python IDE Aprogrammer 6 240 Aug-14-2018, 02:22 PM Last Post: Aprogrammer is this any good? Skaperen 3 437 Feb-25-2018, 02:02 AM Last Post: Skaperen Good morning guys! curlyti 3 434 Feb-14-2018, 12:55 AM Last Post: micseydel What makes a good programmer? j.crater 5 660 Dec-08-2017, 05:08 PM Last Post: Larz60+ Good ID3 module? Ofnuts 1 870 Jun-09-2017, 10:31 PM Last Post: snippsat is it considered good practice to ... Skaperen 9 1,606 May-10-2017, 02:42 AM Last Post: Skaperen Approach to coding, good/bad j.crater 27 4,482 Apr-29-2017, 03:32 PM Last Post: ichabod801 A pretty good Book listing snippsat 4 1,743 Nov-08-2016, 11:05 PM Last Post: Larz60+

Forum Jump:

Users browsing this thread: 1 Guest(s)