8000 `with` statement in loop takes cyclically increasing time · Issue #5622 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content
with statement in loop takes cyclically increasing time #5622
Open
@dhalbert

Description

@dhalbert
import pyb

class WithTest:
    def __init__(self):
        pass
    def __enter__(self):
        pass
    def __exit__(self, *exc):
        pass

x1 = pyb.Pin(pyb.Pin.board.X1, pyb.Pin.OUT_PP)

# CYCLICALLY INCREASING INTERVALS
wt = WithTest()
while True:
    with wt as wtx:
        x1.value(not x1.value())

#OK: CONSTANT INTERVALS
while True:
    with WithTest() as wt:
        x1.value(not x1.value())

The first loop in this test program produces a cyclically increasing square wave. I tested on a PyBoard v1.1 with v1.94 and the also the latest build pybv11-20200208-v1.12-154-gce40abcf2.dfu

The period of the waveform increases from about 38 microseconds to about 240 microseconds. Then there's a gap (gc?) and it starts over.

If you comment out the first loop and use the second (which constructs the with object over and over), it runs at a constant 180 microseconds or so.

The fact that it's a with statement is important; The as is not necessary. We first discovered this while doing I2C transactions in CircuitPython which were taking too long. It took a while to figure out that it was not an I2C issue, but was solely due to the with.

I don't see why the with should inherently cause this behavior, so I think there's something going on in the VM that's slowing things down on each iteration, probably allocating storage which finally gets gc'd. But why should we see an increasing interval? It's like something is walking down an increasingly longer list.

This is easiest to see on an oscilloscope:
https://youtu.be/tGB2uVwig_4 (unlisted; use the link)

Screen shots from Saleae:
first loop (taken at gap: starts fast after a gap and slows down):
Selection_129

second loop (constant before and after gap):
Selection_130

Also filed as adafruit#2602.

Metadata

Metadata

Assignees

No one assigned

    Labels

    py-coreRelates to py/ directory in source

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0