rustc typeck timings
(Following up on my comment on the rust IDE rfc)
Here are some performance numbers for a type inference prototype (demoed here), which uses the rustc libraries to generate resolution and type inference information. It runs from scratch against the source code and rlibs with nothing pre-indexed/loaded, and prints the type of the expression highlighted by the cursor.
As I mentioned in the comment, it speeds up the parsing and analysis stages by selectively stripping function bodies as the text is loaded by rustc, replacing them with whitespace and newlines so that the coordinates are the same. I cribbed the code to do this from racer, which has some fast routines for iterating over logical blocks of rust source.
As a target I analysed the rustc_typeck crate.
On my laptop (2ghz x64 ubuntu):
- Phase 1 (parse input): ~50ms (includes stripping the function body text prior to ast parsing)
- Phase 2 (expand) : ~132ms
- Phase 3 all other checks expect body typeck: ~390ms
- Body typeck for single function: - ~19ms
The results suggest to me in this environment we could get a type-signature level index of this crate achieved in ~ half a second, and then perform the body typecheck on the current local scope after each keypress. We would then need to perform an additional step using the type-signature index to deduce the completion results.
The steps for a type-based completion query ( e.g. foo.<caret>
) are:
- deduce the type of the expression to be completed (i.e. the stuff before the dot)
- generate suggestions by resolving the type and finding e.g. methods, fields, trait impls
Regardless of the level of prior cached indexing, we potentially need to perform the type step (1) on each keypress. This means we should aim to get rustc answering this question in < 100ms (hopefully much less). I suspect this will require some custom compiler work in addition to the current incremental compilation effort.
We could theoretically do (2) without an index directly from the sourcecode and rlibs, (racer currently attempts to do this from source). However this is complicated especially in the face of macros. A rustc generated index would make this simpler and faster, and the index only needs to be at the type-signature level to perform this specific query (i.e. we don’t need information about the contents of functions except for the local scope we are currently searching from).
With the field search occurring outside of rustc we can also be more relaxed about consistency and versioning - e.g. we could perform the search on an old index if we don’t have the most up-to-date one generated yet, since updates outside the current scope will be limited.