We have no real idea what the performance of the finished port is going to be. Early results are encouraging, but it is entirely possible this will be ~20% slower in some cases.
> Fish also uses threads, for things like the autosuggestion and syntax highlighting, and we would like to have more "threads"/"concurrency"/"run-thing-in-backgroundness" (please insert the correct term here, I have never been good at these things). One large project has been to run multiple fish builtins and functions "at the same time", to enable things like backgrounding functions (ideally without using "subshells" because those are an annoying environment boundary that shows up in surprising places in other shells), and to simply be able to pipe two builtins into each other and have them actually process both ends of the pipe "simultaneously".
> C++ offers few guarantees on what can be accessed from which thread. @ridiculousfish has been trying to crack this for years, and hasn't been confident enough in his solution. We want a tech stack that helps us here, and C++ doesn't.
The initial rewrite may be no faster, or possibly slower as stated, but long-term they'd be able to safely add more concurrency or parallelism that they weren't able to before.
The advantages of Rust come when trying to do complex things with concurrency, and wanting to know that they're either going to be safe, or fail to compile.
Strictly, C++ pretty much has to be no slower than Rust. But it's certainly possible that a regular human might in practice write higher-performing parallel code when using Rust.
At the same time Rust forbids some practices pushing a coder to choose another path. To name a specific example, try to roll out your own dynamically sized type type or a self-referential one. Such small things could contribute to performance too.
Yes, there are definitely things one may do in C++ that aren't possible in Rust. In the absence of bugs, I think you could pretty much recreate any Rust program in C++ and have it be just as fast.
Of course, you can't assume the absence of bugs in real world software. The C++ version would lack any of the safety added by Rust's compile time checks.
The real difference is in compile-time abstractions. It's much easier to organize things in Rust, especially with a borrow checker. You can confidently remove overhead while being sure that it'll continue to be memory safe.
With some strong design decisions, and with modern C++ facilities, you can make sure that your code never does funny things in C++, too.
Yes, Rust's BC is a great technology, but C++ is not a runaway nuclear fire which contaminates and melts everything around it when it comes to sanity and security.
Yes, Rust allows you to run amok by not allowing it, but you can design a good foundation to your code which prevents tons of problems out of the gate in C++, and this is without using smart-pointers and other things available to you.
> but you can design a good foundation to your code which prevents tons of problems out of the gate in C++,
And there is an almost perfect overlap between the people capable of pulling off a rewrite like this and the people who would write a good C++ foundation in the first place.
> Yes, Rust's BC is a great technology, but C++ is not a runaway nuclear fire which contaminates and melts everything around it when it comes to sanity and security.
I never meant to imply such a thing. However, Rust is simply a much better-defined language. Moves do what you expect, smart pointers work like you'd expect, there are not 3 (or 5) different types of constructors you have to understand and implement properly if you want to build your own abstractions. You don't have to remember where to put std::move, you don't have to remember what happens to the variable after you move out of it, you don't have to use the awful variant accessor functions if you want a tagged union and so on.
Yes, you can do all this in C++. You can build safe abstractions. You can build layers on top of the STL to make it less awful. You can make use of modules and #embed and other nice new features that C++ is getting. But you need to be a lot more careful compared to Rust, because the compiler is not going to help you.
In Rust it’s easier to leverage external crates/libraries that are more optimised than rolling your own. This can lead to performance increases
(I don’t know if fish is doing this)
It definitely makes a difference around threading; exposing thread safety in function API makes it easy to understand where/how you can add threading support, or what is preventing it.
This is only true for very simple single-threaded code. Once you’re doing anything the compiler can’t trivially optimize, you’re using libraries, getting left far behind by the Rust program, or both.
> Since most industrial software is in C and C++ an example would be more convincing.
Agreed- do you have any to back up your original claim?
> > doing anything the compiler can’t trivially optimize
> What does compiler optimization have to do with libraries?
One of the most common reasons to use a library is because it has optimizations you want to use. For example, performance-sensitive programs link against OpenSSL even if they’re just using a couple of hash functions because the SHA-256 function you copied into your codebase won’t have their assembly backend or use of processor intrinsics. Repeat for string searches, pattern matching, all kinds of math, etc. where people have written libraries with pricessor-specific assembly, SIMD intrinsics, etc.
> Plenty of C and C++ programs are multi threading using a system api like pthreads.
Yes - and the long history of bugs related to that is why many stayed single-threaded because it was more work than the author had time for to make the code thread-safe. Rust’s “fearless concurrency” talk isn’t just marketing but a reaction by people with a lot of experience in the area realizing just how much more they used concurrency when it was easy to do correctly rather than infamously hard.
When C programmers do crypto they also use OpenSSL, but more for security than performance. Do you have an example of a rust library which is a better substitute for commonly hand written C?
> fearless concurrency
Not related to the topic of discussion about performance gains of using libraries.
Is shell performance a limitation for some workflows? I naively think of it as some glue which shunts the work elsewhere. Maybe in the efficiency of pipe? I suppose those lunatics who write full programs in bash?
I will always take faster code, but that seems like an odd bulletpoint to highlight given the many quality of life improvements fish has to offer.
Kind of, yeah. When I used zsh, oh-my-zsh made the shell startup a lot slower, even though I wasn’t going crazy with the customizations. Opening a new terminal tab would take a couple seconds to get a prompt. My current fish setup is imperceptibly fast to start.
Those little delays add friction. Not an intolerable amount, sure, but it’s there. While I switched to fish for other reasons, that alone would keep me from going back now.
>Kind of, yeah. When I used zsh, oh-my-zsh made the shell startup a lot slower, even though I wasn’t going crazy with the customizations
A lot or most of that wasn't zsh being slow though, but oh-my-zsh calling out to external programs (like git to get powerline info and such) and them being slow.
See my other comment from earlier today[1] – launching 230 external programs (even very simple ones, /bin/[ in this case) takes about half a second. Since I would rate anything as >100ms to be a "noticeable delay" you have a "budget" of about 40 external processes, probably a bit less in real-world conditions (depending on which utilities you're using and what it's doing).
And that's 40 C processes. "python empty.py" takes about 30ms to 40ms due to the interpreter startup time; empty C file is about 2ms, "sh empty.sh" is about 4ms.
Please think that "launching external programs is fast and modern computers are fast, so why worry about this?", and that's true, but it's also not. Add up a few dozen and turns out it's actually quite slow.
True, but I can get the same functionality with fish without the slowdown. I don’t think zsh is bad. I understand what was making it slow. I’m just glad I can have all of those niceties plus fish’s speed.
I once spent a while adding timings between each item in my zsh config files to find what was slowest.
The nvm init was the worst of it, so now I have an alias for
`$NVM_DIR/nvm.sh ] && \. "$NVM_DIR/nvm.sh" && \. $NVM_DIR/bash_completion` I just run manually before using nvm, rather than letting it slow me down half a second or whatever it was every time I open a new terminal.
It's worth poking around if things get slow enough to be a pain. There's a decent chance it's 1-2 things that you don't even care about all that much.
If it takes 5 seconds for your prompt to display or become interactive, yes.
As far as I'm aware, most of the other quality of life improvements can be reproduced in zsh with plugins. This performance bulletpoint makes me want to consider switching back to fish from zsh.
> one of the fastest shells out there will probably get even faster […] my terminal productivity has gone up a lot.
Surely you’re not typing and managing jobs at a pace where C vs C++ vs Rust vs $lang matters… or I’m missing something about what fish is bringing to the table.