Freezing code and modules

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Jim.S
Posts: 84
Joined: Fri Dec 18, 2015 7:36 pm

Re: Freezing code and modules

Post by Jim.S » Sat Mar 17, 2018 1:30 pm

I agree that the -X option doesn’t seem to do anything. I carried out some simple tests comparing the performance of functions imported from a .py module against the same function imported from a couple of .mpy files. One mpy file (performace_testC.mpy) was built using no options (mpy-cross performance_testC.py) the other (performance_testB.mpy) was built using the "-X emit=viper" option (mpy-cross -X emit=viper performance_testB.py)

When I ran the code (see below) I demonstrated the expected improvement in execution speed from the .py module using the function decorators, but no improvement in performance using .mpy module built using the -X option.
MicroPython v1.9.3 on 2017-11-01; PYBLITEv1.0 with STM32F411RE
Type "help()" for more information.
>>>
PYB: sync filesystems
PYB: soft reboot
Count: 1738251
Count native: 2739933
Count viper: 5333539
Count_C: 1731672
Count_C viper/int(millis()): 545414
Count_B: 1735226
Count_B viper/int(millis()): 545415
This is the main.py

Code: Select all

import pyb
import performance_test as pt# .py file
import performance_testB as ptB#.mpy file with -X emit=viper
import performance_testC as ptC #mpy file  without -X option 
pt.performanceTest()
pt.performanceTest_native()
pt.performanceTest_viper()
ptC.performanceTest()
ptC.performanceTest_viper()
ptB.performanceTest()
ptB.performanceTest_viper()
This is the performance_testB/C source .py file - the only difference being the print statement

Code: Select all

import pyb # this needs to be in the main for a .mpy file 
def performanceTest():
    millis = pyb.millis
    endTime = millis() + 10000
    count = 0
    while millis() < endTime:
        count += 1
    print("Count_B: ", count)
#@micropython.viper
def performanceTest_viper():
    millis = pyb.millis
    endTime = int(millis()) + 10000
    count = 0
    while int(millis()) < endTime:
        count += 1
    print("Count_B viper/int(millis()): ", count)
def main():
    performanceTest()
    performanceTest_native()
    performanceTest_viper()
if __name__ == "__main__":
    main()
performance_test.py is one of standard micropythyon benchmark programs

Code: Select all

import pyb
def performanceTest():
    millis = pyb.millis
    endTime = millis() + 10000
    count = 0
    while millis() < endTime:
        count += 1
    print("Count: ", count)

@micropython.native
def performanceTest_native():
    millis = pyb.millis
    endTime = millis() + 10000
    count = 0
    while millis() < endTime:
        count += 1
    print("Count native: ", count)

@micropython.viper
def performanceTest_viper():
    millis = pyb.millis
    endTime = int(millis()) + 10000
    count = 0
    while int(millis()) < endTime:
        count += 1
    print("Count viper: ", count)

def main():
    performanceTest()
    performanceTest_native()
    performanceTest_viper()
if __name__ == "__main__":
    main()


User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Freezing code and modules

Post by Roberthh » Sat Mar 17, 2018 4:13 pm

If you do the same on the board, you'll see a difference. Results for Pyboard
Pure python : 2909438
Native emitter: 4714648
Viper emitter: 8493894
But since you code contained a call to an pyb.millis(), the advantage of viper is not that obvious. Result with that changed code (lower is better):

Code: Select all

import pyb
#@micropython.viper
def performanceTest():
    count = 0
    while count < 1000000:
        count += 1

start = pyb.millis()
performanceTest()
print("Elapsed time:", pyb.millis() - start)
Pure Python: 2594
Native emitter: 1134
Viper emitter: 108
So the typical strategy would be to isolate the timing critical parts of the code and have that as python source on your device, and precompile or freeze in flash the other part, which often is the bulk of the code.

Post Reply