kopia lustrzana https://github.com/micropython/micropython
Added a good example for range vs while vs pointer arithmetic
rodzic
d927ee8951
commit
9b313453b3
|
@ -557,7 +557,7 @@ def function_returns_object(x)->object:
|
|||
|
||||
## Range vs. while
|
||||
|
||||
`range()` does work under viper, so you could write: ```for x in range(10)```. It is a bit faster to use a while loop, with viper ints for j, limit and step.
|
||||
`range()` does work under viper, so you could write: ```for x in range(10)```. It is a bit faster to use a while loop, with viper ints for j, limit and step.
|
||||
```py
|
||||
limit:int = 100
|
||||
step:int = 2
|
||||
|
@ -567,6 +567,53 @@ def function_returns_object(x)->object:
|
|||
j += step
|
||||
```
|
||||
|
||||
You can also use pointer arithmetic to get rid of a counter to control the while loop, and that's even faster! Using pointer arithmetic also enables to use `p[0]` instead of `p[I]`, again an improvement. The timing was done on a 80Mhz Cortex-M3 in the W600:
|
||||
```py
|
||||
from array import array
|
||||
from time import ticks_us, ticks_diff
|
||||
|
||||
a = array('i', (2*i+1 for i in range(10000)))
|
||||
|
||||
@micropython.viper
|
||||
def vip_add1(p: ptr32, l: int) -> int:
|
||||
r:int = 0
|
||||
for k in range(l): # range() works, but is not fastest
|
||||
r += p[k] # accessing with p[i]
|
||||
return r
|
||||
|
||||
@micropython.viper
|
||||
def vip_add2(p: ptr32, l: uint) -> int:
|
||||
r:int = 0
|
||||
k:uint = uint(0)
|
||||
while k < l: # a while loop is faster
|
||||
r += p[k] # accessing with p[i]
|
||||
k += 1
|
||||
return r
|
||||
|
||||
@micropython.viper
|
||||
def vip_add3(p: ptr32, l: uint) -> int:
|
||||
r:int = 0
|
||||
pstop: uint = uint(p) + 4*l
|
||||
while uint(p) < pstop: # directly looping the pointer to the array and indexing
|
||||
r += p[0] # with p[0] is faster than accessing with p[i]
|
||||
p = ptr32(uint(p) + 4) # casts necessary because the types are fixed in viper
|
||||
return r
|
||||
|
||||
|
||||
t0 = ticks_us()
|
||||
sum1 = vip_add1(a, len(a)) # --> 100000000
|
||||
t1 = ticks_us()
|
||||
sum2 = vip_add2(a, len(a)) # --> 100000000
|
||||
t2 = ticks_us()
|
||||
sum3 = vip_add3(a, len(a)) # --> 100000000
|
||||
t3 = ticks_us()
|
||||
|
||||
print('vip_add1:', sum1, 'time:', ticks_diff(t1, t0)/10000, 'µs per it.') # --> 0.7064 µs
|
||||
print('vip_and2:', sum2, 'time:', ticks_diff(t2, t1)/10000, 'µs per it.') # --> 0.5767 µs
|
||||
print('vip_and3:', sum3, 'time:', ticks_diff(t3, t2)/10000, 'µs per it.') # --> 0.3635 µs
|
||||
```
|
||||
|
||||
|
||||
## Global variables
|
||||
If you need to do integer arithmetic with a global variable, this works:
|
||||
```py
|
||||
|
@ -746,7 +793,7 @@ Step by step with a real problem: https://luvsheth.com/p/making-micropython-comp
|
|||
|
||||
The MicroPython tests for viper have some examples, see all cases prefixed by "viper_": https://github.com/micropython/micropython/tree/master/tests/micropython
|
||||
|
||||
The issue that gave origin to this wiki page, with interesting discussions: [#14297](https://github.com/orgs/micropython/discussions/14297)
|
||||
The issue that gave origin to this wiki page, with interesting discussions. This also is the source for some examples here: [#14297](https://github.com/orgs/micropython/discussions/14297)
|
||||
|
||||
Search https://forum.micropython.org and https://github.com/orgs/micropython/discussions for viper. There are many insights and examples.
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue