]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
tools: ynl: try to avoid the very slow YAML loader
authorJakub Kicinski <kuba@kernel.org>
Wed, 3 Jun 2026 21:08:10 +0000 (14:08 -0700)
committerJakub Kicinski <kuba@kernel.org>
Thu, 4 Jun 2026 22:36:12 +0000 (15:36 -0700)
Turns out Python YAML defaults to a pure Python loader for YAML
files which is a lot slower than the C loader (using libyaml).
Try to use the C one whenever possible.

The avg time to run:
  $ tools/net/ynl/pyynl/cli.py --family tc --no-schema
drops from 300+ ms to 115 ms with this change (40 samples).

We could drop the load time further to 85 ms if we "compiled"
the specs to JSON. Slightly tricky parts are that we don't
currently install the specs at all on make install, so it's
unclear where to put the conversion. Also JSON has questionable
support for comments and we need an SPDX line.

Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
Link: https://patch.msgid.link/20260603210810.2636193-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
tools/net/ynl/pyynl/lib/nlspec.py

index fcffeb5b7ba3af93ca414573ce35ddf3a73169aa..0469a0e270d059ce7f9e49099a2b5d1c0417ae47 100644 (file)
@@ -439,6 +439,11 @@ class SpecFamily(SpecElement):
     # To be loaded dynamically as needed
     jsonschema = None
 
+    try:
+        _yaml_loader = pyyaml.CSafeLoader
+    except AttributeError:
+        _yaml_loader = pyyaml.SafeLoader
+
     def __init__(self, spec_path, schema_path=None, exclude_ops=None):
         with open(spec_path, "r", encoding='utf-8') as stream:
             prefix = '# SPDX-License-Identifier: '
@@ -448,7 +453,7 @@ class SpecFamily(SpecElement):
             self.license = first[len(prefix):]
 
             stream.seek(0)
-            spec = pyyaml.safe_load(stream)
+            spec = pyyaml.load(stream, Loader=self._yaml_loader)
 
         self.fixed_header = None
         self._resolution_list = []
@@ -464,7 +469,7 @@ class SpecFamily(SpecElement):
             schema_path = os.path.dirname(os.path.dirname(spec_path)) + f'/{self.proto}.yaml'
         if schema_path:
             with open(schema_path, "r", encoding='utf-8') as stream:
-                schema = pyyaml.safe_load(stream)
+                schema = pyyaml.load(stream, Loader=self._yaml_loader)
 
             if SpecFamily.jsonschema is None:
                 SpecFamily.jsonschema = importlib.import_module("jsonschema")