From 493a75291db3fed8c3b190823f3ad14c70fb0835 Mon Sep 17 00:00:00 2001 From: Dixing Xu Date: Sat, 7 Nov 2026 21:30:29 +0000 Subject: [PATCH] perf(pyutils): 2.5x faster natural_comparison_key (schema sort keys) Return (key,) at once for names with letters only, which cannot contain a decimal digit. For other names, replace the digit parts of the regex split in one slice assignment instead of walking the parts with zip and itertools.cycle. The keys stay exactly the same. Sort keys for all GitHub schema names: 63.70 ms -> 25.62 ms. Co-Authored-By: Aiden --- src/graphql/pyutils/natural_compare.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/graphql/pyutils/natural_compare.py b/src/graphql/pyutils/natural_compare.py index 9c357cc6..86bb8d17 100644 --- a/src/graphql/pyutils/natural_compare.py +++ b/src/graphql/pyutils/natural_compare.py @@ -3,7 +3,6 @@ from __future__ import annotations import re -from itertools import cycle __all__ = ["natural_comparison_key"] @@ -15,7 +14,9 @@ def natural_comparison_key(key: str) -> tuple: See: https://en.wikipedia.org/wiki/Natural_sort_order """ - return tuple( - (int(part), part) if is_digit else part - for part, is_digit in zip(_re_digits.split(key), cycle((False, True))) - ) + # letters only (no decimal digits) is the common case, check it cheaply first + if type(key) is str and key.isalpha(): + return (key,) + parts = _re_digits.split(key) + parts[1::2] = [(int(part), part) for part in parts[1::2]] + return tuple(parts)