Skip to content

Conversation

@gudnimg
Copy link
Contributor

@gudnimg gudnimg commented Dec 20, 2025

Replace yaml.compose() with a faster event-stream parser that extracts the first top-level compatible scalar without constructing the full YAML node tree.

This reduces per-file parsing overhead when iterating over thousands of binding files. Binding files are now opened in binary mode and passed directly to SafeLoader/CSafeLoader.

Benchmark (Windows, Python 3.12.3, 2913 bindings):

  • before: 874ms, 641862 function calls
  • after: 603ms, 188557 function calls

Benchmark (Ubuntu 24.04, Python 3.12, 3388 bindings).

  • latest Zephyr main as of writing which is 5a58989:
  • before: 466ms, 746041 function calls
  • after: 170ms, 118802 function calls

So on my end I'm seeing the following improvements:

  • Windows: ~30% improvement
  • Linux: ~60% improvement

On Windows half the time, 300ms, is spent on opening 2913 binding files. While on Ubuntu it is only 32ms for 3388 files. Which explains a larger difference between the OS performance.

Testing Method

def main()
    import cProfile, pstats, io
    from pstats import SortKey
    pr = cProfile.Profile()
    pr.enable()
    
    # code under test is placed here

    pr.disable()
    s = io.StringIO()
    sortby = SortKey.CUMULATIVE
    ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
    ps.print_stats()
    print(s.getvalue())

Replace yaml.compose() with a faster event-stream parser that extracts
the first top-level "compatible" scalar without constructing the full
YAML node tree.

This reduces per-file parsing overhead when iterating over thousands of
binding files. Binding files are now opened in binary mode and passed
directly to SafeLoader/CSafeLoader.

Benchmark (Windows, Python 3.12, 2913 bindings):
- before: 874ms, 641862 function calls
- after:  603ms, 188557 function calls

Half of the time is spent opening and closing files, which is quite a
bit faster on Linux.

Signed-off-by: Guðni Már Gilbert <[email protected]>
@gudnimg gudnimg force-pushed the opt-gen-driver-kconfig-dts-py branch from 98d562d to a65323e Compare December 20, 2025 15:14
@sonarqubecloud
Copy link

Copy link
Contributor

@JarmouniA JarmouniA left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it work with child-bindings?
ex.

compatible: "ti,tca9544a-channel"

@gudnimg
Copy link
Contributor Author

gudnimg commented Dec 20, 2025

Does it work with child-bindings? ex.

compatible: "ti,tca9544a-channel"

@JarmouniA My initial thought is no, its just ignored as the value is not at root-level. The contents of the output file Kconfig.dts is the same as before so I wouldn't expect any change in behavior. I'll double check this again 👍


Unrelated, I just discovered why Windows is so slow on my end. Turns out one of my disk drives has a lot more file filters:

C: drive:

fltmc instances -v C:

Instances for C: volume:

Filter                  Altitude        Instance Name       Frame   SprtFtrs  VlStatus
--------------------  ------------  ----------------------  -----   --------  --------
bindflt                  409800     bindflt Instance          0     0000000f
UCPD                     385250.5   UCPD - Top Instance       0     0000000f
WdFilter                 328010     WdFilter Instance         0     0000000f
storqosflt               244000     storqosflt                0     0000000f
wcifs                    189900     wcifs Instance            0     0000000f
gameflt                  189850     gameflt Instance          0     0000000b
CldFlt                   180451     CldFlt                    0     0000000f
bfs                      150000     bfs                       0     0000000f
FileCrypt                141100     FileCrypt Instance        0     0000000f
luafv                    135000     luafv                     0     0000000f
Wof                       40700     Wof Instance              0     0000000f
FileInfo                  40500     FileInfo                  0     0000000f

While on my D drive:

fltmc instances -v D:

Instances for D: volume:

Filter                  Altitude        Instance Name       Frame   SprtFtrs  VlStatus
--------------------  ------------  ----------------------  -----   --------  --------
UCPD                     385250.5   UCPD - Top Instance       0     0000000f
WdFilter                 328010     WdFilter Instance         0     0000000f
gameflt                  189850     gameflt Instance          0     0000000b
bfs                      150000     bfs                       0     0000000f
Wof                       40700     Wof Instance              0     0000000f
FileInfo                  40500     FileInfo                  0     0000000f

I see almost 2x better performance in opening/closing files! 300ms reduced to 138ms. Very interesting... will look into this further :)

@JarmouniA
Copy link
Contributor

The contents of the output file Kconfig.dts is the same

Huh, so we were ignoring child-bindings all this time, interesting! I hope there is no usage of a DT_HAS_{CHILD-COMPAT}_ENABLED Kconfig symbol in-tree.

@gudnimg gudnimg marked this pull request as ready for review December 20, 2025 19:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants