Description
On src/racer/ast.rs
, there are multiple methods whose implementation looks something like this:
let thread = Thread::scoped(move || {
let stmt = string_to_stmt(s);
let mut v = ImplVisitor { name_path: None, trait_path: None };
visit::walk_stmt(&mut v, &*stmt);
return v;
});
return thread.join().ok().unwrap();
Since this is using Thread::scoped
(which makes the parent thread wait on the thread.join()
call), there isn't any gain in performance here - on the contrary, there's a big performance loss. On my linux system, a call to racer complete std::old_io::
spawns 108 threads, and spends almost half of its execution time on the futex
syscall (thread synchronization).
On a comment, there's a possible justification for this - handling panic!
s from the parser, since Rust provides no way to "catch" panic!
s. The problem with this justification is twofold - first, methods as the one above (which are by far the most common on the file I mentioned) aren't actually catching anything, since they unwrap()
the final result of thread.join()
- meaning that a panic!
will be propagated to the parent thread anyway. Secondly, per rust-lang/rust#22435, "catching" panics at the border of a scoped
thread won't be supported by the stdlib anymore - which means that racer won't be able to use this technique anymore in a few days.
I'm opening this issue so that we can discuss a possible solution for this - hopefully one that doesn't use threads for control flow :)