1
0
mirror of https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git synced 2026-10-24 00:48:53 +03:00
Files
libgpiod/bindings/python/gpiod/_internal.py
Vincent Fazio 5524758ab4 bindings: python: _internal: collapse isinstance checks
The two isinstance checks can be combined to a single call that uses a
tuple of types to check against.

When 8c9d5b4 was prototyped, it originally used a single call but it
was falsely micro-optimized to use two separate calls due to the single
call being slower.

The performance overhead was likely due to the tuple of types being
created on each iteration of the loop. Using a module variable with the
proper types avoids this overhead.

  $ python3 -m timeit -s "x = 42; T = (int, str)" "isinstance(x, T)"
  20000000 loops, best of 5: 13.9 nsec per loop
  $ python3 -m timeit -s "x = 42" "isinstance(x, int) or isinstance(x, str)"
  20000000 loops, best of 5: 14.6 nsec per loop
  $ python3 -m timeit -s "x = 42" "isinstance(x, (int, str))"
  10000000 loops, best of 5: 30 nsec per loop

Fixes: 8c9d5b4 ("bindings: python: make config iteration consistent")
Signed-off-by: Vincent Fazio <vfazio@gmail.com>
Link: https://patch.msgid.link/20261020003728.13669-4-vfazio@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
2026-10-20 15:08:42 +02:00

40 lines
1.0 KiB
Python

# SPDX-License-Identifier: LGPL-2.1-or-later
# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@bgdev.pl>
from __future__ import annotations
from datetime import timedelta
from select import select
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from collections.abc import Generator, Iterable
from .line_settings import LineSettings
__all__ = ["config_iter", "poll_fd"]
_LINE_ID_TYPES = (int, str)
def poll_fd(fd: int, timeout: timedelta | float | None = None) -> bool:
sec: float | None
if isinstance(timeout, timedelta):
sec = timeout.total_seconds()
else:
sec = timeout
readable, _, _ = select([fd], [], [], sec)
return fd in readable
def config_iter(
config: dict[Iterable[int | str] | int | str, LineSettings | None],
) -> Generator[tuple[int | str, LineSettings | None]]:
for key, settings in config.items():
if isinstance(key, _LINE_ID_TYPES):
yield key, settings
else:
for subkey in key:
yield subkey, settings