Windows-rs: Improve performance of code generation

Created on 11 Jun 2020  路  5Comments  路  Source: microsoft/windows-rs

Despite only taking ~10% of the total time to compile winrt bindings, currently the actual generation of the code is too slow. We should be able to improve this. We can use this repo to run profiling tools to see how long things are taking.

In my first look over the code, I don't see anything too egregious. It might be that quote and proc_macro2 are simply not optimized to generate as much code as we are generating.

enhancement performance

Most helpful comment

An update on our progress here. The introduction of the squote crate has significantly helped code generation time (down to about 2% of what it was before). Unfortunately, this is only about 10% of the compilation time. We're working with the rustc perf team on helping with the rest. Because of WinRT's object-oriented nature, it maps fairly poorly to Rust's type system. We have to generate _a lot_ of std::convert::From bindings in order to simulate this. The current implementation in the compiler is O(n2) for resolving trait impls which is not normally an issue in Rust programs as the n tends to be small, but is definitely an issue for WinRT-rs. There's an initial prototype of a fix in rustc that shows promise cutting the compile times down by ~40%. More testing is needed, but hopefully this would be a quick win.

All 5 comments

Update: I have a branch that with switches to using strings instead of TokenStreams when generating the code. This takes only ~20% of the time as generating TokenStreams, so the performance improvement is pretty significant, and I believe it opens up further performance improvements like multithreading that would probably not be possible when using TokenStreams since those make heavy using of thread local storage. This change was done by updating the quote crate to support a string backed quote!-like macro. I'm waiting to hear from the maintainer whether this is an approach they would be interested in maintaining. Otherwise, we will have to create our own crate for it.

FYI. We're using stress-rs and stress-cpp to compare Rust/WinRT with C++/WinRT - basically worst case bindings. Here are the relative numbers so far:

| | Intel | AMD |
| -- | -- | -- |
| C++ | 43 sec | 89 sec |
| Rust | 35 min | 55 min |
| | 48 x slower | 37 x slower |

Intel i7-8700K 6-Core
AMD Ryzen Threadripper 1950X 16-Core

Unfortunately, this is all largely single-threaded but clearly there's room for improvement. 馃槈

Thanks for sharing the information, Kenny. This sure looks like there is a lot of opportunity left untapped. Recalling how you pushed C++/WinRT's performance, even when it was generally accepted that it could not possibly be made to compile any faster, just upped my expectations for Rust/WinRT, tenfold.

In the (unlikely) case that you haven't seen this already: Intro to rustc's self profiler explains, how to profile the Rust compiler using the -Zself-profile nightly option. Though it can be set up to profile an entire crate graph, it wasn't immediately obvious to me, whether this can be used to gather timing information with enough detail to attribute it to the individual steps in the code generation process.

An update on our progress here. The introduction of the squote crate has significantly helped code generation time (down to about 2% of what it was before). Unfortunately, this is only about 10% of the compilation time. We're working with the rustc perf team on helping with the rest. Because of WinRT's object-oriented nature, it maps fairly poorly to Rust's type system. We have to generate _a lot_ of std::convert::From bindings in order to simulate this. The current implementation in the compiler is O(n2) for resolving trait impls which is not normally an issue in Rust programs as the n tends to be small, but is definitely an issue for WinRT-rs. There's an initial prototype of a fix in rustc that shows promise cutting the compile times down by ~40%. More testing is needed, but hopefully this would be a quick win.

Closing this as there's no actionable work here. The Rust compiler needs a lot of work and we'll continue to push for that.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rylev picture rylev  路  5Comments

tim-weis picture tim-weis  路  3Comments

DJankauskas picture DJankauskas  路  3Comments

ZCWorks picture ZCWorks  路  3Comments

rylev picture rylev  路  4Comments