Rendered at 12:43:08 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
kstrauser 7 hours ago [-]
I have a complex fish shell configuration with ~100 autoloaded functions and about 180 lines across config.fish and a dozen conf.d/ files.
On my system, hyperfine says fish loads in about 85ms:
Benchmark 1: fish -il -c exit
Time (mean ± σ): 85.0 ms ± 3.3 ms [User: 50.1 ms, System: 31.4 ms]
Range (min … max): 82.9 ms … 101.1 ms 28 runs
And that's without giving up a single thing in the name of quickness. Stick with zsh if you want, but understand that there are tradeoffs. And for the fish end of those tradeoffs: 1) most command lines work identically between fish, zsh, and bash; 2) where they don't, the fish version is nearly always more pleasant and obviously correct for interactive use; and 3) you don't have to uninstall bash, ya know — you can still `curl foo | sh` to run some random script off the net if you feel the desire. Your existing stuff doesn't stop working.
adrian_b 6 hours ago [-]
On my 6-year old PC, an interactive zsh starts more than 4 times faster, but this is a rather minor detail.
Which are in your opinion the advantages of fish over zsh?
The fish tutorial from its Web site highlights some very important advantages of fish over bash/ksh/sh, but all of them are taken from zsh, which had them long before the creation of fish (e.g. features that eliminate the need for the excessive quotation that is necessary in bash/ksh/sh).
Fish has various syntactic differences in comparison with zsh, in some places fish is more concise, but in others it is more verbose, and it is more verbose in things that are more frequently used (e.g. "set" vs. "=", "and" vs. "&&" etc.), while being more concise in things that are more rarely used.
Therefore, from the fish tutorial I see why it is preferable to bash/ksh/sh, but I see no reason to prefer it to zsh.
kstrauser 6 hours ago [-]
This is my go-to example:
Say you want to make an autoloaded function in zsh. Go ahead and look that up. Unless you're one of the zsh maintainers, you probably don't have that syntax memorized. I don't mean that personally. The whole time I used zsh, I certainly didn't remember it and had to look it up each time.
In fish, you define a function named "foo" in a file in a specific directory: ~/.config/fish/functions/foo.fish. That's the entire process. When you type "foo" at the command line, and fish can't find that command anywhere, it'll look in that directory for foo.fish, and if it finds it, it'll load that file and execute the "foo" function defined inside it.
Now, say you want to customize your zsh prompt and have it show you the output of a couple of commands, maybe with some colors. It's a fun exercise to try to get something working purely from memory, but that's a test I never managed to pass.
Want to do it in fish? Follow that pattern above to define an autoloaded function called "fish_prompt". Put it in ~/.config/fish/functions/fish_prompt.fish. It's just a normal function where you can use "echo" and "git" and any other command on your system to write the components of your prompt to stdout. That's it. You're done. There's no step 2. Any other time I want to draw something on the screen, I'd use a series of shell commands to write it out to the screen, so why shouldn't it work exactly the same way for my shell prompt? Well, with fish, it does.
That expirement ruined bash and zsh for me. I don't spend a lot of time continually customizing my shell prompt, but the once every couple of years I want to, it's a huge relief to know I just have to edit that function to write out my new idea and that's the end of it. There's just so much less magic to learn and remember with fish that I don't want to go back.
And to be clear, I know my way around several other shells. I love fish because I've used the others enough to become very competent with them, not because I don't know the others or they're too hard for me or anything like that. By programming language analogy, I'm capable of writing decently sized programs in a few flavors of assembler. But man, life's too short to use it for everything, unless that's just the kind of hair shirt you're into wearing.
adrian_b 6 hours ago [-]
Thanks.
I use a rather complicated zsh prompt, complicated enough so that I could never convince bash to execute an equivalent prompt correctly, despite the fact that the features used by the prompt are supposed to be supported in bash too.
(The prompt syntax is quite different in zsh and in bash. This is the zsh syntax of my prompt:
PS1=%F{cyan}"[%T %n@%m:%~]"$'\n'%#%f
)
As you say, to be able to write the prompt I had to study carefully the zsh manual.
However, I consider this a minor disadvantage, because I have written the prompt many years ago, when I have switched from bash to zsh, and I have never had any reason to change it.
I agree that for rarely used features it is more likely to be necessary to search the manual for zsh than for fish, but for me this happens seldom enough to not consider it a decisive disadvantage.
kstrauser 5 hours ago [-]
I do get that, and thought that way too at first. In my case, I found that it being so trivially easy to do these 2 things made them things I did more often. Go ahead and make a thousand convenience scripts and aliases for whatever mischief you want to get up to. There’s no measurable effect on startup time between have 1 autoload function and 1,000. Because it’s free, and so dead simple to do, I never avoid it anymore. There’s no worrying of my startup script’s getting too long and slowing things down, so there’s no downside to doing the things that make my life easier.
For me, it unlocked a completely different mindset. Fish isn’t for everyone, any more than chocolate or steak are, and that’s cool. I’m glad we have options.
thallavajhula 7 hours ago [-]
That's a ridiculously low number. Wow! I don't think my personal mac has such speed either. I should definitely try this out.
- also you should put a list of all your article. (titles only) on some page called /archive or something
- i really dont want to scroll 5000 pages to see the last 20 articles you wrote
- just a suggestion from a ui / ux perspective
thallavajhula 9 hours ago [-]
will add a page, thanks for the suggestion.
adrian_b 9 hours ago [-]
Even the final starting time for zsh from TFA is quite bad.
On a 6-year old desktop PC with a Ryzen CPU, an interactive zsh starts in 20 ms and a login zsh starts in 60 ms.
The configuration file for the interactive zsh, i.e. "~/.zshrc", has 75 lines and it configures completions (in the default manner added to ~/.zshrc by compinstall), binds some keys, sets umask and some shell options and defines a bunch of environment variables (including the prompt) and of command aliases.
I do not see what else would be needed, which could increase the starting time.
My login zsh takes 40 ms longer because I do not use a GUI login, but the classic CLI login, so the login zsh checks if a GUI desktop session is running and if not it starts the session (obviously, the 60 ms login zsh starting time is for when the GUI session is already running).
tecoholic 12 hours ago [-]
Use mise and you will be in the micro-seconds region.
Because of the performance and stability issues I moved to fish for 1 year and I like it even more, it's syntax, functions it's tab completions, for some reason with zsh I always had an issues, my bad, but fish work perfectly out of the box.
AprilArcus 18 hours ago [-]
How did I know it was going to be `nvm` before I clicked?
supriyo-biswas 18 hours ago [-]
All the package managers that provide shell wrappers kinda tend to be bad at this, unless they use their own command to wrap over project specifications, like uv.
These days, I've been personally relying more on direnv to automatically activate certain shell configurations, and then nix to manage binary dependencies like node or go or php.
jdxcode 16 hours ago [-]
mise isn't, and has the advantage that you don't need to build your own lightsaber with direnv and nix.
ricardobeat 16 hours ago [-]
In my experience direnv is also a source of slowness. How fast is it for you?
drdexebtjl 14 hours ago [-]
My understanding is that nix-direnv caches the environment, so after you first evaluate it, it’s pretty much instant.
I haven’t timed it, but it’s not perceptible imo.
ricardobeat 16 hours ago [-]
Having gone through the same experience, I suggest dropping fnm as well; I don’t recall what exactly causes it, but it will eventually slow down too.
I’ve been using mise [1] to manage node versions since with zero issues.
I haven't had any issues with `fnm` so far. It's been fast and I like how it prompts you to install a missing node version as soon as you jump into a directory with a `.nvmrc` file.
c-hendricks 14 hours ago [-]
Mise does similar, but for a while suite of tools instead of just nodejs.
thallavajhula 14 hours ago [-]
Will check it out, thanks!
jasonpeacock 10 hours ago [-]
Huh, I just ran the same timing command for my fish shell (with starship prompt) and got 168ms.
My mini-story: I'd switched to zimfw which does a ton of caching, precompiling. It benches very well versus other zsh frameworks. But something was still taking almost a second for me, every time. https://github.com/zimfw/zimfw
On my system, hyperfine says fish loads in about 85ms:
And that's without giving up a single thing in the name of quickness. Stick with zsh if you want, but understand that there are tradeoffs. And for the fish end of those tradeoffs: 1) most command lines work identically between fish, zsh, and bash; 2) where they don't, the fish version is nearly always more pleasant and obviously correct for interactive use; and 3) you don't have to uninstall bash, ya know — you can still `curl foo | sh` to run some random script off the net if you feel the desire. Your existing stuff doesn't stop working.Which are in your opinion the advantages of fish over zsh?
The fish tutorial from its Web site highlights some very important advantages of fish over bash/ksh/sh, but all of them are taken from zsh, which had them long before the creation of fish (e.g. features that eliminate the need for the excessive quotation that is necessary in bash/ksh/sh).
Fish has various syntactic differences in comparison with zsh, in some places fish is more concise, but in others it is more verbose, and it is more verbose in things that are more frequently used (e.g. "set" vs. "=", "and" vs. "&&" etc.), while being more concise in things that are more rarely used.
Therefore, from the fish tutorial I see why it is preferable to bash/ksh/sh, but I see no reason to prefer it to zsh.
Say you want to make an autoloaded function in zsh. Go ahead and look that up. Unless you're one of the zsh maintainers, you probably don't have that syntax memorized. I don't mean that personally. The whole time I used zsh, I certainly didn't remember it and had to look it up each time.
In fish, you define a function named "foo" in a file in a specific directory: ~/.config/fish/functions/foo.fish. That's the entire process. When you type "foo" at the command line, and fish can't find that command anywhere, it'll look in that directory for foo.fish, and if it finds it, it'll load that file and execute the "foo" function defined inside it.
Now, say you want to customize your zsh prompt and have it show you the output of a couple of commands, maybe with some colors. It's a fun exercise to try to get something working purely from memory, but that's a test I never managed to pass.
Want to do it in fish? Follow that pattern above to define an autoloaded function called "fish_prompt". Put it in ~/.config/fish/functions/fish_prompt.fish. It's just a normal function where you can use "echo" and "git" and any other command on your system to write the components of your prompt to stdout. That's it. You're done. There's no step 2. Any other time I want to draw something on the screen, I'd use a series of shell commands to write it out to the screen, so why shouldn't it work exactly the same way for my shell prompt? Well, with fish, it does.
That expirement ruined bash and zsh for me. I don't spend a lot of time continually customizing my shell prompt, but the once every couple of years I want to, it's a huge relief to know I just have to edit that function to write out my new idea and that's the end of it. There's just so much less magic to learn and remember with fish that I don't want to go back.
And to be clear, I know my way around several other shells. I love fish because I've used the others enough to become very competent with them, not because I don't know the others or they're too hard for me or anything like that. By programming language analogy, I'm capable of writing decently sized programs in a few flavors of assembler. But man, life's too short to use it for everything, unless that's just the kind of hair shirt you're into wearing.
I use a rather complicated zsh prompt, complicated enough so that I could never convince bash to execute an equivalent prompt correctly, despite the fact that the features used by the prompt are supposed to be supported in bash too.
(The prompt syntax is quite different in zsh and in bash. This is the zsh syntax of my prompt:
)As you say, to be able to write the prompt I had to study carefully the zsh manual.
However, I consider this a minor disadvantage, because I have written the prompt many years ago, when I have switched from bash to zsh, and I have never had any reason to change it.
I agree that for rarely used features it is more likely to be necessary to search the manual for zsh than for fish, but for me this happens seldom enough to not consider it a decisive disadvantage.
For me, it unlocked a completely different mindset. Fish isn’t for everyone, any more than chocolate or steak are, and that’s cool. I’m glad we have options.
- also you should put a list of all your article. (titles only) on some page called /archive or something
- i really dont want to scroll 5000 pages to see the last 20 articles you wrote
- just a suggestion from a ui / ux perspective
On a 6-year old desktop PC with a Ryzen CPU, an interactive zsh starts in 20 ms and a login zsh starts in 60 ms.
The configuration file for the interactive zsh, i.e. "~/.zshrc", has 75 lines and it configures completions (in the default manner added to ~/.zshrc by compinstall), binds some keys, sets umask and some shell options and defines a bunch of environment variables (including the prompt) and of command aliases.
I do not see what else would be needed, which could increase the starting time.
My login zsh takes 40 ms longer because I do not use a GUI login, but the classic CLI login, so the login zsh checks if a GUI desktop session is running and if not it starts the session (obviously, the 60 ms login zsh starting time is for when the GUI session is already running).
https://arunmozhi.in/2024/09/06/replacing-pyenv-nvm-direnv-w...
https://asdf-vm.com
These days, I've been personally relying more on direnv to automatically activate certain shell configurations, and then nix to manage binary dependencies like node or go or php.
I haven’t timed it, but it’s not perceptible imo.
I’ve been using mise [1] to manage node versions since with zero issues.
[1] https://mise.jdx.dev
What all is happening in the Zsh profile?
zprof helped me and the LLM profile and we found it was one plugin, which wasn't really intended specifically for zim. Fixed that! https://github.com/lipov3cz3k/zsh-uv/issues/2
Man it feels so good having shells just open so lightning fast.