Skip to content

Performance fix for slcan #2027

@aaronfultonnz

Description

@aaronfultonnz

Describe the bug

There is a performance issue with the way the reads are implemented in slcan.py.

_read() reads serial data one byte at a time via read(1), even when multiple bytes (or complete frames) are already buffered in the OS serial receive buffer. Each read(1) incurs a syscall and, when no data is available, blocks for up to the serial timeout (default 1ms). A typical SLCAN frame is ~27 bytes, so each frame requires 27 separate read(1) calls minimum. This causes per-frame read latency of 50–850ms instead of <1ms (particularly on windows which seem to have sub-optimal serial support).

I'm using CAN-TP over CAN-FD, so I'm pushing this to the limits, which is why the performance issue has shown up.

Expected behavior

The serial is read as fast as possible

Additional context

OS and version: Windows 11
Python version: 3.10
python-can version: 4.6.1
python-can interface/s (if applicable): Canable2 running SL CAN firmware with FD support

The Fix

I'll submit a pull request with a suggested fix that alters the serial read behaviour to be significantly faster.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions