Because Martin was the lead maintainer and original author and worked at Google for over a decade until like a month ago, and so as a project it fell under their typical standards in the Google OSPO department and had a CLA applied. When it moved orgs, they had to own the org too, so they could keep CLA robot in. That's basically it. It's just a really successful project that has grown far beyond one company or person.
In theory there is now nothing stopping us (the community/project leaders) from just... Moving the repo somewhere else. We could do that. It would be a pretty sudden alienation of other Google contributors though and probably piss off their legal department -- 99% of them just submit regular fixes like any user, because they are ordinary users of JJ. They just happen to work at Google. It would just be stirring up shit for nothing. It isn't an unthinkable outcome, but it isn't one we're just going to "do" for no reason or because it would make people posting on forums happier.
Realistically a non-ownership-assigning CLA on a non-copyleft Apache 2.0 project like in this case doesn't actually mean anything or confer any power. It's all just paperwork that serves as a legal ass covering mechanism because big companies use lawyers. It's like checking the "Yes I am over 18 years old" box on a website. I say this as someone who hates the stupid CLA bot and am a contributor.
As far as actual leadership goes Google does not "own" anything in that regard, nor the day to day work, nor can it really force any of the community to do anything. There's 1 maintainer from Google out of 9 total and +95% of major contributions don't come from Googlers, ERSC, or even any particular company. They don't contribute most of the code, they don't lead most of the community, they are vastly dwarfed by the community in total size, contribution count, etc. What "ownership" or leverage do they have beyond a Github org in this setup? It's annoying but it isn't the same thing as being able to exercise meaningful levers of power, in my experience, and so most of us are just fine with it. Even if there was some stupid bullshit like a disagreement over implied trademark rights, the community could just rename and move on and Google would have nothing. That is where the real power lies.
I'm trying to come from a place of help, truly, so bear with me.
You have to get out from under Google. This would be a red flag during due diligence for many investors.
I'm not saying Google is going to fuck you over but why not just get yourself into a place where you don't need to be writing replies like this, and we don't need to be having this conversation.
And also, I would strongly recommend acquiring trademark rights as soon as possible. If a foundation is formed later you can decide what to do with them, but having them protected is a huge deal.
There's nothing starting me from creating jjhub.com tomorrow and that is a real potential threat for you.
Since I posted previously, I realized I had forgotten trademark entirely, and Google does own the trademark for jj. (See my other comments about the Mozilla/Rust connection, it was the same back then too).
It's not an issue for investors, because again, Google does not own this, and we aren't even modifying jj at this point, and are unlikely to need to. The IP is very clear and not an issue.
> There's nothing starting me from creating jjhub.com tomorrow and that is a real potential threat for you.
That's fine! There's a lot of people already doing this, today. Competition is natural.
Jujutsu also started out very small, just like Git did. The core concepts aren't too complex. But this is 2026, not 2005 or 2019. Most of the modern Git implementations are extremely large, highly optimized and featureful codebases that are difficult to replicate. Many of Git's performance and structural improvements over the last few years have nontrivial implementations and designs. Jujutsu is also a large, featureful codebase. You can't build a modern Git implementation with all of the highly optimized goodies (multipack indicies, partial clones, etc) and a good UX without a lot of code and work. Or any version control system, frankly. It's just how it is.
- Gitoxide is 80,000+ lines of code.
- Git itself is over 170,000 lines of code.
- Even "Game of Trees" or "got" by the OpenBSD developers, which is a wholly separate project that has its own porcelain, is +120,000 LOC.
- Jujutsu itself is about 100,000 LOC.
- JGit for Java is around 200,000 LOC.
These are all roughly approximate and include things like testing code (but I think that's fair because tests are part of the project). All of these projects started small years ago, and are now large.
> If jj is not too complex to have multiple implementations, why have new implementations not sprung up by now?
"Make multiple implementations" is not, in and of itself, particularly valuable without some underlying justification to do so. It also is not how (AFAIK) any other version control system has ever worked; Git's "identity" as an on disk format is a particular design choice (with pros and cons), so yes you can get multiple tools with varying levels of features that agree on the basic disk format and poke at it. But most projects just don't work this way, much less other VCSs; there also aren't really many "Linux re-implementations" beyond toys because it is easier to just collectively contribute with each other, because Linux is not a "standard" written in stone, but a living and breathing thing.
The CLA is Google's in this case. It gives them the right to distribute your copyrighted work. It also has some terms that say Google could sublicense and redistribute the jj codebase under another license -- which means they could for example release a copy of the jj code that was under MIT, or GPL2, MIT-Apache, etc. Or proprietary, even.
But the thing is, Jujutsu is under the Apache 2.0 license right now. You are within your rights to use Apache 2.0 in proprietary products. Literally anyone, at this exact moment, could clone the repo and integrate it into a proprietary product, or share proprietary binaries built on the code (rename it Gugutsu VCS) without giving up the source, as long as they obey the ASL 2.0 terms. The CLA really has nothing to do with this fact.
If you are personally worried about your personal copyrighted patches going into proprietary products -- or if that's your only worry -- you basically need to avoid contributing to all projects that are not using a copyleft license; just avoiding CLAs or whatever isn't enough. This has been true for a while.
If you are worried about a "rug pull" the next question is whether the developers can actually do that. That is a matter of social configuration of the project, not licenses. The thing with "rug pull OSS projects" is mostly about ownership and labor. Licenses and CLAs really don't matter much if 99.8% of development comes from one group of unified engineers. Such a setup is risky even with a 0% chance of any license changes. Their company might fail or they might all get fired. You didn't get rug pulled, but the project might die, which is basically just as bad.
But for Jujutsu, there is no majority of developers from any one company, and significant amount of code comes from the community, so the answer is more or less "no, we can't do that even if we wanted." The best we could do is start a whole fork and lose a significant chunk of the community and contributors. There isn't any one group of people with enough of an iron grip to do that without sustaining massive losses.
I think people sort of get "Can this become proprietary", with "Is some <bad outcome> possible" -- in this case Jujutsu's code can absolutely "become" proprietary already in a real way. You can just go do that now. But a lot of "rug pull" things are prevented, I think, simply due to the fact we have a robust and strong community outside the (paid) developers
Ultimately, for a non-copyleft project, non-assigning CLAs like the one Jujutsu has are basically just annoying, legal ass covering mechanisms for Google's sake. I also do not like the CLA, it's just basically an irrelevant piece of paper as far as my principles on the matter are concerned. The Linux kernel DCO is basically just a CLA with fewer words, motivated by similar concerns to not get backstabbed due to the business logic of suing people.
If we got rid of the CLA for Jujutsu, I personally think it would probably still be nice to ask people to respect the DCO.
reflog can't quite catch every change that might happen because not everything is stored directly as a ref (ie a "head" that git tracks, like a branch pointer).
For instance, if you are interactively using `git bisect` and you mark commits as good or bad, and you accidentally mark a commit incorrectly, you have to do something like:
The reflog can't really capture this kind of thing, hence why you have a bisect log -- now a wholly separate concept that exists independently of the reflog.[1]
Another example is when you do something like screw up an interactive rebase. Let's say you rebase 20 commits and then you get a conflict on commit 8. You fix the file conflicts, and continue. You accidentally solve the merge incorrectly, continue and get another conflict -- but only realize your mistake after you start solving it. The reflog can't save you here. You have to completely abandon the rebase and start over. (This specific example might be handled better these days).
I think the biggest thing about `jj undo` is that it works everywhere. You can undo rebases, merges, conflict resolutions, copies, deletions, whatever. The secret behind it all is that internally, jj is architected in a way where implementing a feature looks like you are working with a transactional database. You actually have `begin_transaction()` and `commit()` methods in the codebase that will make changes to the commit graph visible in an atomic way. When a command like `jj rebase` happens, all of the changes it makes are inside a transaction and committed at once. Every operation in the repo is a transaction, and it all goes into a log, which records the effects of a transaction -- very much like a database system!
So "undo" just means "undo the effects recorded in a transaction" and that is about all. And so it works for everything! And this design is very easy to intuitively understand and program against, as a maintainer, along with our other high level internal APIs. Any developer can easily write code that Just Does The Right Thing and the user can undo it and it's no big deal. When I develop and work on Jujutsu myself -- like I'm actively developing new features or prototyping ideas -- I almost always _use my own jj repository_ as a test repo while testing my builds.
In contrast, Git does not have one unified "transactional" layer for things like this. But not all is lost, there has been work on 'git undo' and it was implemented by... Someone who is now a Jujutsu maintainer[2]. :)
[1] Technically we do not yet have "step by step" bisect with good/bad yet (only "automatic" bisect that is one-shot), so that is something Git can do we can't do at all right now, but bear with me. :')
You can speak the git protocol over the network only, but one advantage of using the same storage on disk as Git and exposing it in the same way (in a manner that keeps jj/git in sync) is that git-based tools still work. So, people still get diff markers in the gutter of their editor buffers, random scripts that do `git rev-parse` or whatnot still work out of the box, etc. This makes the experience more seamless and imposes less friction on non JJ users, eg you do not have to write a patch and add a special case for JJ because `git rev-parse` failed to run and then ask pretty please to merge it (and then keep doing that forever as you are the only user).
It doesn't sound like much, but before I started contributing to Jujutsu I was a user of https://sapling-scm.com/ -- Sapling is fantastic. It stores data on disk in git format, but back then it was not exposed to the user by default -- the .git directory is hidden away. It actually ended up causing a lot of friction that random `git` commands would not work, or tools had other various git-based behaviors. These days, sapling has a "dotgit" mode (partially inspired by jj I assume) that puts the .git directory in the root dir, so `git` commands still work.
Beyond that though, speaking Git over the network only has other complications on the client side. In particular Git clients and servers negotiate what objects each side has (given what the client requests), and from that negotiation derives a list of needed objects to give the client, and then sends a packfile for it. This is all relatively expensive to do on demand, actually, so it would make the interactivity for network operations much worse if you need to wholly translate your storage into packed objects, etc. And doing it efficiently would require you keeping a cache around that is basically a git database anyway, so you might as well just go ahead and use it. Not the end of the world in terms of downsides, but a trade-off that adds some baggage.
We (East River Source Control) don't run Jujutsu, it does not "belong" to us -- it is a community project! Nothing has or is changed. Most of the contributors have nothing to do with us/Google/whoever. We get tons of great contributions from highly experienced and talented individuals. It's healthy, check it out: https://github.com/jj-vcs/jj/commits/main/
Most of the maintainer stuff is also overhyped in a way (OSS maintainer-heads know this). The maintainer group is largely structured to just keep things moving; not really a privilege but a responsibility -- making sure things get merged, doing technical reviews, ensure builds are unstuck, and hitting the green approval button. Our own community members also do code review, find bugs, triage things, answer questions, design features, help get users unstuck, etc. We are very much not alone, and I have great confidence in the constitution and strength of the community itself as someone who has been around the block a few times.
This is going to sound silly and "guy approves of himself" adjacent, but I've been doing OSS maintainer stuff for like 2 decades at this point, and jj is truly a gem as a project. It is vibrant, and the community is generally speaking insanely talented (huge number of git powerusers), and we have a weird dogfood advantage where people use the tool to contribute right back to it. Martin did an awesome job setting the tone of the project just through his behavior before many of us joined years ago. He's a naturally good project lead.
As I said elsewhere: I work for ERSC and I am a Jujutsu maintainer. This is just me speaking candidly on my own behalf.
> git can do everything jujutsu can do (otherwise, jujutsu couldn't work with git).
FWIW I think it's a bit more nuanced than that. As a trivial counter example Git does not currently have a way to store conflicts inside commits[1], which is one of our major features. The way this works is that we basically store the sides of the conflicting trees in the Git object database (and another conflicted tree pointing to all of them), but the actual data structure representing the conflict as Jujutsu understands it is stored elsewhere. Git will be very confused looking at a conflicted tree object created by Jujutsu -- it shouldn't break but it doesn't understand what it's seeing. So, if a object can be stored in the database that is correct but Git can't really "view" it properly, does "git" (or capital-G Git) support it or not? Depends on who you ask, I guess. The storage layout being intimately tied to Git "as a thing", part of its identity, is one of the most interesting properties it has.
The way I see it is this. Jujutsu uses the Git storage layout on disk. But basically all of the algorithms and UX between the two are completely different. That is where most of the real differences are. To the extent we integrate with lots of fiddly Git details (eg tracking branches, remote integration etc) so that `git` commands work -- that's more necessity to make the UX nice. We could absolutely use the on disk Git format but in a way that was inscrutible to the `git` CLI, it just obviously would not be very nice.
As a disclosure I work at ERSC but I am also one of the maintainers of Jujutsu; this post is written with my maintainer hat on.
[1] At Git Merge last year, Elijah Newren prototyped and demo'd a really early and cool example of storing first class conflicts in Git, based on his work on ort-merge. So this might not be true forever :)
> As a trivial counter example Git does not currently have a way to store conflicts inside commits[1], which is one of our major features.
Yes, I like how jj does it!
Did a big `git rebase -i` yesterday and I felt stressed up, almost a bit angry, when there were some conflicts and I wasn't sure if I'd resolve all of them before it was time to leave, and work more later from a different laptop.
But with jj, no stress: I can just check in the conflicts, and later, on the other laptop: check out the conflicts and continue resolving.
(I just wish there was Git submodule support :- ))
macOS absolutely has sandboxing, what are you talking about? But the reality is that you need custom sandboxing tools less when you don't have basic problems like "anything that runs ever can read my ~/.ssh directory without problem" or "you can hijack my password by interposing sudo and thus do anything". This does not matter because macOS will see a program signed by Corp XYZ is trying to read data not owned by that cryptographic signature, and it can't escape the code signature check, and it will flag it. A program cannot simply read your password from stdin and elevate privileges silently, because granting new privileges requires communicating with a higher privilege program so it can delegate to you, and that program has a non spoofable prompt. And so on.
You can use Linux's sandboxing functionality to make a pretty hardened server. If you take in mind the physical deployment and go the extra mile, it can be very secure. The Linux desktop is not and will never be secure in its current form from things like extremely basic local malware. You would have to redesign much of the desktop stack from the init system downward so you could easily do things signature-based identity, proper per-identity secure storage and key management, securitizing elevation of privileges, getting rid of setuid, etc.
No, musl's allocator is just bad even in completely normal programs, and it is especially awful if you are using even two threads much less a lot of them. It has no TLABs or arenas. It has a single global mutex over alloc/free paths. It does syscalls underneath that lock (mmap) meaning the few fast paths it has are rarely taken under contention and have to fall back to futex wakes, so even 2 threads with minor contention and allocation rate will have visible wait points in profiles, stuck waiting for the allocator. It returns mapped memory to the OS very eagerly when a size class is empty, so even single allocs followed by a single free can cause thrashing as it mmaps/unmmaps things repeatedly for a size class over and over. Etc. You quite literally have to limit your thread count when using musl, because it will tank the performance of actually highly threaded programs that can scale with core count, even at very modest allocation rates and small working set sizes.
Its string routines and memory copy routines are also similarly bad, as the article alludes to. They are just naive loops with nearly no optimization. These are not small insignificant functions where using them is "doing it wrong", they are the backbone of vast amounts of code and can be made multiple times faster. You can similarly see string routines pop up in profiles all the time in musl builds in my experience. And unlike the memory allocator these cannot be "fixed" systematically across the application at link time, so you are stuck with it.
Real programs have to often do things like allocate memory and use multiple threads and process strings. People have been optimizing these things for decades, there is vast amounts of prior art, the musl developers simply did not do so because they prioritize simplicity over nearly everything else (from what I can tell) including performance.
It has a single global mutex over alloc/free paths. It does syscalls underneath that lock (mmap)
Every default malloc implementation worked this way about 12 years ago. Making lots of small allocations, even from multiple threads then blaming the allocator is a losing strategy. An allocator is only going to be able to mitigate the damage to speed and interactivity.
The solution is and always has been to make larger allocations and use those efficiently.
They are just naive loops with nearly no optimization.
The compiler should be able to take something with good access patterns and make something fast, especially out of the basic C functions.
they are the backbone of vast amounts of code
Performance wise it's unlikely C string functions are actually the bottleneck in a program. Maybe for specific programs a naive memory copy function could benefit from AVX instructions.
Real programs have to often do things like allocate memory
"Have to" and "often" are debatable. Any allocations in a hot loop are the very first things that should be optimized away after profiling.
>Performance wise it's unlikely C string functions are actually the bottleneck in a program. Maybe for specific programs a naive memory copy function could benefit from AVX instructions.
Many programs use lots of strings. It tends to become a bottleneck. It also tends to be very difficult to improve because the strings are everywhere in that kind of program, and refactoring to eliminate them is either impossible or very risky.
Many programs use lots of strings. It tends to become a bottleneck.
I would dispute this in anything that isn't mostly about string processing and in that case you can always easily grab different string functions, which you should probably do anyway if strings are that important.
It also tends to be very difficult to improve because the strings are everywhere in that kind of program,
I don't know what 'that kind of program' is supposed to mean.
and refactoring to eliminate them is either impossible or very risky.
This doesn't sound like a general purpose statement that applies to anything broadly.
All I'm saying is the the title is wrong and musl doesn't do much to prevent speed in a program. If someone was really trying to optimize, blaming the standard library is not going to get them very far and it's easy to work around, but needing to do that is very rare.
>I would dispute this in anything that isn't mostly about string processing and in that case you can always easily grab different string functions, which you should probably do anyway if strings are that important.
I'm telling you that I've seen it, in stuff as diverse as video games and robotics. Lots of things use strings as values. It's easy to say "just change everything in millions of lines of code" when you aren't the one who has to make that change.
By the way most software does copious amounts of string processing... I think that should be common knowledge, but I guess it isn't.
>This doesn't sound like a general purpose statement that applies to anything broadly.
You sound like you have zero experience. If your config is in strings, and hundreds of thousands of lines of code already rely on the string-ness of the data, then you just can't make the change easily.
>All I'm saying is the the title is wrong and musl doesn't do much to prevent speed in a program. If someone was really trying to optimize, blaming the standard library is not going to get them very far and it's easy to work around, but needing to do that is very rare.
I believe the title is accurate. People in performance-sensitive areas gripe about libraries, even standard libraries, quite often. I don't mean to insult you but you're making bold assertions despite clearly lacking the experience to know how things are done in industry generally.
To be clear, you're saying that in video games and robotics people are using strings instead of numbers and when that becomes a performance problem you think simple C string functions are to blame? How about not using strings as values?
By the way most software does copious amounts of string processing... I think that should be common knowledge, but I guess it isn't.
It isn't because it's not true if "copious" is about CPU time. String processing is rarely the bottleneck.
I believe the title is accurate
Well, it isn't. It's unlikely that musl prevents anyone from making a fast program. It doesn't even make sense. In the off chance anything was a real bottleneck you could bring in something faster and you would want to do that anyway.
People in performance-sensitive areas gripe about libraries, even standard libraries, quite often.
I have done a lot of optimization and I've never seen the standard library be a problem for exactly what I just outlined.
A lot of what you're saying is just "it's a problem because it is, trust me". That isn't evidence or an explanation.
As soon as allocation is slow you can avoid allocations (which you should do anyway) or use a different one (which you would do even with a standard libc anyway).
If you really have string problems (and not some fake problem like just parsing strings over and over instead of caching values) then you would use an optimized library. The benefit from a regular libc over musl is minuscule compared to the real solutions to optimizing.
you're making bold assertions despite clearly lacking the experience to know how things are done in industry generally.
Trying for insults doesn't add any sort of technical explanation. To be very clear any program written by someone who says their memory allocator is their bottleneck is something I could speed up by orders of magnitude and the standard library isn't going to matter.
>To be clear, you're saying that in video games and robotics people are using strings instead of numbers and when that becomes a performance problem you think simple C string functions are to blame? How about not using strings as values?
To bring this back to the article, the problem is actually that one library does this worse than others. If you are unfortunate enough to already rely on these functions performing up to a certain standard, then having them become dramatically worse is in fact an issue.
Why don't you just not use slow functions? Well, that goes back to my references to refactoring. Even if you could get approval to refactor the stuff, it's still risky and a lot of work. Compare that to just not using an oddball standard library with worse performance...
>Well, it isn't. It's unlikely that musl prevents anyone from making a fast program. It doesn't even make sense. In the off chance anything was a real bottleneck you could bring in something faster and you would want to do that anyway.
THAT IS THE POINT OF THE ARTICLE TITLE: If you require performance in certain key areas, MUSL may not be acceptable.
>I have done a lot of optimization and I've never seen the standard library be a problem for exactly what I just outlined.
The article here is literally complaining about a standard library's performance, which is not uncommon in the blog-o-sphere. So, you are ignoring evidence right in your face. People like me are telling you it sometimes matters, and people blog about such problems frequently, but you still aren't getting it.
I can only tell you vaguely about codebases I've worked on. I can't tell you where, or show you code, or anything like that. Get used to it.
>A lot of what you're saying is just "it's a problem because it is, trust me". That isn't evidence or an explanation.
Everything you've said is "It's NOT a problem because I'VE never seen it be a problem!" When the evidence is right in front of your face and people are telling you, yes, it is a problem. Do you think I'm getting paid to share this wisdom with you?
If you don't think string processing is a bottleneck, you should consider how many applications are document-based and string-based. Basically, it's a MAJORITY of applications in the world, and I'd put money on that.
>As soon as allocation is slow you can avoid allocations (which you should do anyway) or use a different one (which you would do even with a standard libc anyway).
More "just refactor bro" or "just use a different library" (the point of the article). Only one of these is likely to be practical in any given situation, especially since MUSL is not the default for most stacks.
>The benefit from a regular libc over musl is minuscule compared to the real solutions to optimizing.
Bro, if the stats in the article are right (and I have no reason to doubt) the difference is significant (at least numerically). It's easy to tell other people to go do a ton of work to optimize. The radically easier solution is to just not use MUSL if that's your problem. Again, the entire point of the article.
>Trying for insults doesn't add any sort of technical explanation.
Saying you're inexperienced is not insulting, especially since you're a stranger. You clearly deny having experience with the stuff I'm talking about, which I think is common-knowledge in optimization circles, and then insist on labor-intensive solutions to easily solved problems. Some insulting thoughts have crossed my mind here but I know we've all been inexperienced at some point, so I'm trying to keep it civil to teach you something.
>To be very clear any program written by someone who says their memory allocator is their bottleneck is something I could speed up by orders of magnitude and the standard library isn't going to matter.
This is youthful arrogance (I can only assume you're young; if not, you at least haven't matured in your career). It's not always possible to do such optimization, from either a technical perspective or a pragmatic one. Most people do not have authority to go on an optimization binge across their codebases, assuming the penalty is even paid by their own code (it often comes from upstream libraries!). Even if you did have the authority, expertise, and time to do the optimization, it could be a horrible idea and introduce a LOT of potential bugs.
I like the idea of MUSL, and wish the project well. I may even use it for something one day. But none of this makes their performance better. It may be that getting better performance would compromise their other objectives, such as simplicity.
If you are unfortunate enough to already rely on these functions performing up to a certain standard, then having them become dramatically worse is in fact an issue.
There are a few problems here. The first saying that anything is dramatically worse. The second is thinking that nothing can be changed. The third is thinking that there are lots of programs out there that spend all their time in C string functions yet nothing can be altered except for linking in a different standard library.
I can't tell you where, or show you code, or anything like that. Get used to it.
I didn't expect at any point that you to be able to back up what you are saying with examples.
Everything you've said is "It's NOT a problem because I'VE never seen it be a problem!"
That couldn't be further from the truth. I'm saying it isn't a problem because the problems are easily fixable and musl doesn't prevent them from being fixed.
You hallucinated a quote and made up something completely different in your head.
If you don't think string processing is a bottleneck, you should consider how many applications are document-based and string-based. Basically, it's a MAJORITY of applications in the world, and I'd put money on that.
You think these programs are bottlenecked by the C-string functions in their standard library? That's a bold claim. Why would a program completely dependent on strings even use C string functions in the first place? You have to scan to a newline to find the length, they work with ascii and they are known to be incredibly insecure. What you're saying doesn't make sense.
You clearly deny having experience with the stuff I'm talking about,
I deny that there are programs that can only be sped up by switching to a different C library and nothing else, since that's nonsense.
just not use MUSL if that's your problem.
People can do whatever they want, all I've ever said is that musl doesn't prevent anyone from making a fast program. That's it.
Saying you're inexperienced is not insulting,
I'll take your word for it because you seem extremely inexperienced at optimizing, especially if you think making fast software should include leaning on C strings and having memory allocation show up on your profiler.
This is youthful arrogance (I can only assume you're young; if not, you at least haven't matured in your career).
You can go for the insults and try to be patronizing again, I expect that as the last resort of someone frustrated that repeating their claim isn't taken as evidence. I explained a lot in detail about why musl isn't going to prevent anyone from writing fast software because I've done it over and over.
You seem to be saying that you can speed up legacy programs somewhat that weren't made well in the first place with a faster libc and I'm sure that's true, but it has nothing at all to do with the premise the musl prevents a program from being fast or even is much of a bump in the road.
The speed ups from a more optimized libc are percentage points shaved off the the times where you actually use it. Using better string functions, minimizing allocations and paying attention to memory access patterns are going to be order of magnitude changes. Minimizing allocations is going to be at least 7x on a single core, better memory access patterns are going to be 20x-25x.
You don't have any evidence or explanation that musl prevents someone from writing fast software, which is the title and the title is wrong.
>There are a few problems here. The first saying that anything is dramatically worse. The second is thinking that nothing can be changed. The third is thinking that there are lots of programs out there that spend all their time in C string functions yet nothing can be altered except for linking in a different standard library.
25% slowdown can be dramatic for some applications. Secondly, I didn't say that nothing can be changed. I said that change is expensive. Thirdly, I think linking another library is probably acceptable to get an easy 25% speedup! This problem was probably discovered by somebody saying "Why is this shit so slow when I link with MUSL?"
Regarding "Nothing can be altered except for linking" -- There are many such cases. This especially happens with upstream code. If you use a library that you aren't willing or able to fork, you have to deal with its limitations. This can happen for open-source projects, or for private commercial projects.
>You hallucinated a quote and made up something completely different in your head.
I summarized your whole position in an ironic quote to show you how dumb it is. I'm sorry you don't see how you come off. Calling my rhetoric "hallucination" is laughable. I could swear I'm arguing with a bot.
>I'm saying it isn't a problem because the problems are easily fixable and musl doesn't prevent them from being fixed.
Your fix suggestion amounts to calling for a huge refactoring, as I said. MUSL does not prevent you from doing that, but it's easier to just not link MUSL if it's causing problems for you.
>You think these programs are bottlenecked by the C-string functions in their standard library? That's a bold claim. Why would a program completely dependent on strings even use C string functions in the first place? You have to scan to a newline to find the length, they work with ascii and they are known to be incredibly insecure. What you're saying doesn't make sense.
Performance-sensitive programs and libraries are often written in C. C-string representation is widely used by all programming languages, which are usually written in C or C++ (which uses C).
>I deny that there are programs that can only be sped up by switching to a different C library and nothing else, since that's nonsense.
This statement is the real nonsense. Again with the "I've never seen it, so it can't exist" bullshit.
>People can do whatever they want, all I've ever said is that musl doesn't prevent anyone from making a fast program. That's it.
No, that's not all you've said. You said the title is wrong. You said (roughly speaking) that the choice of standard library is never a decision point for performance. The title of this article may be a bit exaggerated, but there's a clear example of poor MUSL performance in the article. It's also not JUST slow string functions, it's slow memory allocation too. What's next, you gonna say you've never seen a program that needs lots of memory allocation? Or that I should go fork some upstream project to work around MUSL's limitations?
>You can go for the insults and try to be patronizing again, I expect that as the last resort of someone frustrated that repeating their claim isn't taken as evidence. I explained a lot in detail about why musl isn't going to prevent anyone from writing fast software because I've done it over and over.
You can keep saying it over and over and it won't be any more true. It's true that I'm making claims and you're not accepting them. What you should ask yourself is what I have to gain by making these claims. The answer is nothing. I'm beginning to think you're a troll. Your username certainly suggests it.
>You seem to be saying that you can speed up legacy programs somewhat that weren't made well in the first place with a faster libc and I'm sure that's true, but it has nothing at all to do with the premise the musl prevents a program from being fast or even is much of a bump in the road.
I am CLEARLY saying that. Linking MUSL to any program that heavily uses the slow functions will make it slower. Since MUSL is not the default for most software, this will be observed as totally unnecessary and inexcusable performance degradation. If you're trying to build the fastest version of some software, you should use the fastest libraries.
Your position seems to be that the title is wrong because it is theoretically possible to make MUSL-dependent programs fast according to some unstated performance metric, so the title is necessarily wrong. What you don't see is that no matter what performance metric you choose, if I wrote the program to be fast with MUSL, it would be EVEN FASTER with a faster library. It might be "fast enough" for somebody with MUSL alone. But if that somebody cares about performance (like the title says) then they will use the fastest library they can. They won't refactor all their code to make MUSL work faster. Sometimes the objective of caring about performance is to have literally the fastest thing possible, not just "fast enough".
>You don't have any evidence or explanation that musl prevents someone from writing fast software, which is the title and the title is wrong.
The title doesn't say that MUSL will stop you from writing fast software. I never said that either. The title says "Don't use MUSL if you care about performance." But keep burning that straw man bro. I'm done with this bullshit conversation.
25% slowdown can be dramatic for some applications.
What you keep forgetting is that's 25% of the part that you're actually using.
You keep avoiding and denying that for a program where any sort of speed matters you just aren't spending any of your time hitting the C standard library.
If a program is slow because of the C standard library and it needs to be faster, someone messed up a long time ago. That isn't the C libraries fault. You can squeeze a little more out of it if you have find a more optimized library, but it's all a drop in the ocean compared to how much faster it would go by doing basic real optimizations.
Performance-sensitive programs and libraries are often written in C. C-string representation is widely used by all programming languages, which are usually written in C or C++ (which uses C).
You can say that, but really it's almost all C++ and people avoid C strings for exactly why I outlined in detail. You don't have length up front, it's all ascii, you're dealing with pointers to arbitrary runs of bytes, etc.
This is not good for memory access patterns, dealing with lots of characters at one time, dealing with unicode, minimizing memory allocations etc.
It's true that I'm making claims and you're not accepting them.
That is true that you are making lots of claims and that I'm not accepting them, because you don't have any evidence or explanations and they don't make sense.
All I've said is that MUSL doesn't prevent someone from making fast programs and you barely have even confronted that, let alone explained how it isn't true.
Linking MUSL to any program that heavily uses the slow functions will make it slower.
Any program that is hammering the the C standard library can be sped up by orders of magnitude and 25% is nothing. Again, lifting memory allocations will speed something up by 10x, so that 25% isn't going to matter anymore because it's 25% of something that isn't even going to show up on a profiler, let alone be a bottleneck.
Your position seems to be that the title is wrong because it is theoretically possible to make MUSL-dependent programs fast according to some unstated performance metric
I think you mean it's trivially possible according to the detailed explanation I gave from a lot of experience optimizing.
Sometimes the objective of caring about performance is to have literally the fastest thing possible, not just "fast enough".
25% better might be fast enough for you, I like speeding up programs by 100x by changing to C++ instead of C and focusing on the optimizations that matter.
The title says "Don't use MUSL if you care about performance."
I use musl and I care a lot about performance. It doesn't matter because has no bearing on how fast my programs are.
I'm done with this bullshit conversation.
I'm sure it seems that way when someone doesn't accept the same claim over and over without any actual explanation or evidence. Saying the same thing and getting more upset is not an effective way to make your point. You need real information, not insults and fake quotes.
I awoke today with renewed energy to deal with your nonsense, and I think after reading this comment it deserves a (hopefully) short reply.
>I use musl and I care a lot about performance. It doesn't matter because has no bearing on how fast my programs are.
This is the crux of the matter. You clearly have some investment in MUSL, that much has been apparent all along. If you actually USE it, which I'm sure you do, then you are not using the fastest possible library. Regardless of your skill, simply switching to a faster library will make a program faster. Sometimes, that's what is needed. We JUST want to find easy ways to make code as fast as possible. We aren't looking to rewrite the world.
I don't have any investment in MUSL. I wish the project well, but if it's not the fastest library then it will necessarily be unsuitable for some applications.
>What you keep forgetting is that's 25% of the part that you're actually using.
First off, I didn't forget shit. There are surely programs for which the penalty is actually 25% or close to it. The penalty can actually be far worse than that due to algorithmic complexity issues. Secondly, it is quite possible that one could use the standard library almost exclusively. Thirdly, any performance drop could be significant.
>You can say that, but really it's almost all C++ and people avoid C strings for exactly why I outlined in detail. You don't have length up front, it's all ascii, you're dealing with pointers to arbitrary runs of bytes, etc.
C strings are used extensively in C++. Again you prove how inexperienced you are.
>This is not good for memory access patterns, dealing with lots of characters at one time, dealing with unicode, minimizing memory allocations etc.
Keep deflecting with bullshit that is irrelevant to the choice of library, and that can't be changed but for massive refactoring.
>That is true that you are making lots of claims and that I'm not accepting them, because you don't have any evidence or explanations and they don't make sense.
There's only so much evidence and explanation I can provide to strangers on the internet. Then there is also the level of evidence that I can provide, such as other blog posts, that I don't feel like providing. A lot of the things I've said are true a priori (assuming some simplifications), such as the fact that a slower library will always be worse for performance than a faster library. If MUSL is measurably slower than others, then it can be a problem.
>Any program that is hammering the the C standard library can be sped up by orders of magnitude and 25% is nothing. Again, lifting memory allocations will speed something up by 10x, so that 25% isn't going to matter anymore because it's 25% of something that isn't even going to show up on a profiler, let alone be a bottleneck.
As I've said many times, rewriting software is not always on the table. Even minor changes may be forbidden or burdensome for various reasons. What you're talking about is a redesign, that may not be applicable to all cases anyway.
>>Your position seems to be that the title is wrong because it is theoretically possible to make MUSL-dependent programs fast according to some unstated performance metric
>
>I think you mean it's trivially possible according to the detailed explanation I gave from a lot of experience optimizing.
Right, your position is definitely that making these changes is "trivial"... I threw in "theoretically" because I interjected my own knowledge that these optimizations are often only theoretically possible, and can't be done for many practical reasons. My wrong statement of your position made it more defensible than it actually is.
>25% better might be fast enough for you, I like speeding up programs by 100x by changing to C++ instead of C and focusing on the optimizations that matter.
I don't want to get off on another tangent but you are trivializing and exaggerating a lot of stuff in this one statement. Changing languages and altering the code is not an easy win, and might actually trigger a performance setback. Switching to a faster library is a relatively easy win.
>Saying the same thing and getting more upset is not an effective way to make your point. You need real information, not insults and fake quotes.
I've made my point already, you just haven't accepted it. I assume you are either incapable of understanding (perhaps temporarily), or have unstated biases as I pointed out due to being a MUSL enthusiast or contributor. You're not convincing me either way. My position is that people who care about being as fast as possible should use the fastest available library, which clearly isn't MUSL. There may be other valid reasons to use MUSL, and it may be "fast enough", but other libraries are yet faster.
This is how I see your argument so far:
- MUSL is fast enough, trust me bro.
- Ok, maybe someone measured some functions to be slower, but everyone knows that you shouldn't be using the STANDARD LIBRARY heavily. Nobody has ever used strings or memory allocation that heavily, and if they did then they are doing it wrong (even if other libraries provide adequate performance for them).
- If you have a problem with this, you just need to do some trivial optimizations, or change languages to C++. It's SUPER EASY (at least for elite MFers like myself).
- Because rewriting the code to compensate for MUSL performance is always on the table, it's never reasonable to say that MUSL is causing a performance problem.
I only added a slight amount of emphasis. You've been pretty close to that bombastic in the whole exchange. It's ridiculous, and I think you are smart enough to know better but admitting that you are wrong is beyond the pale. Instead of wasting my time, how about applying those elite optimization skills you claim to have to the MUSL code to make it faster. Then you will be able to write a blog like "Don't use glibc if you care about performance" and argue with people on HN if you want. By the way, I didn't write this blog post, and I don't have any other conflicts of interest such as being a glibc developer, so don't start up with that shit either.
C strings are used extensively in C++. Again you prove how inexperienced you are.
You can try to be patronizing if you want, but this doesn't make sense with you not understanding memory access patterns. If someone uses C++ they will use C++ strings. Have you used C++? It works well and it has been around for 40 years, you should give it a try.
Keep deflecting with bullshit that is irrelevant to the choice of library, and that can't be changed but for massive refactoring.
You painting yourself into a corner has nothing to do with a C library being a few percentage points slower. This is not a general scenario, it's something you are dealing with because you can't optimize C strings.
If you think memory access patterns are 'bullshit' you haven't done much optimization. That's everything in modern optimization.
If there is an expert somewhere around you, please talk to them so you can get up to speed on modern optimization. Minimizing allocations is table stakes, memory access is the meat.
If you have any examples on github of things you think "can't" be optimized, go ahead and link it and tell me what a profiler shows, and I will explain what to do.
I've made my point already, you just haven't accepted it.
You made your claim, you haven't had any evidence or explanation, that's how it works. You say the same thing over and over and get more upset, but that isn't evidence. Show me where musl prevents someone from writing a fast program.
Insults and hallucinated quotes aren't a good foundation for proving your point. If you have to pretend that someone said something different, then maybe you aren't really making sense.
how about applying those elite optimization skills you claim to have to the MUSL code to make it faster.
Why would I do that when I don't use the C library for performance sensitive programs? You never seem to be able to confront this. The stuff made 50 years ago isn't the fastest possible stuff. It's still pretty fast and if you want something faster, do something else. It's not that complicated but it seems to really upset you.
I don't have any other conflicts of interest such as being a glibc developer, so don't start up with that shit either.
No one said anything about that, I think you're hallucinating or predicting something that never happened.
Stop spamming me with burning straw men bro. I am slightly irritated with you because I think you're trolling me or at least wasting my time by being an idiot. I have asked some rhetorical questions in my response below. Do not feel obligated to pipe up with more nonsense in response.
>Have you used C++
I mainly work in C++, and have for the past 20 years. That also entails using a fair amount of C from time to time. Even if I didn't write C or C++, the performance of the standard library would affect me, as I use much software written in these languages as well.
>Why would I do that when I don't use the C library for performance sensitive programs?
If you don't use C at all then you aren't using MUSL and won't need it to be fast. If you do use MUSL then you aren't using the fastest library, so you must not care that much about performance.
>No one said anything about that, I think you're hallucinating or predicting something that never happened.
I expected that you might say "what about YOU" when I pointed out your obvious conflict of interest here. That would have been a baseless attack but more logically coherent than what you've been spamming me with.
>The stuff made 50 years ago isn't the fastest possible stuff. It's still pretty fast and if you want something faster, do something else. It's not that complicated but it seems to really upset you.
Finally, just because a project or language is old doesn't mean it currently has bad performance. The article suggests that if you care about performance, don't use MUSL. That is "using something else" and exactly what I've been saying this whole time. Why are you so stubborn that you can't even admit that there could very well exist a scenario where the suggestion to switch to another standard library makes sense? Nevermind that these scenarios are common, and the article is presenting one. You have suggested everything from massive refactoring to switching languages, anything but switching to a more suitable library.
I'm not sure where the entitlement and expectation comes from that you can reply to me and that I won't reply back. This seems like a transparent hail mary to continue to avoid confronting what I already explained in detail.
You can try to call my single replies "spam", but I think if you could actually respond to the things I've said you would have done it already.
If you do use MUSL then you aren't using the fastest library,
You are contradicting yourself with logic that doesn't add up.
The default libc isn't the fastest way to do things anyway. So by your own logic the title should be "don't use libc if you care about performance". This of course doesn't make sense either because if you aren't using libc then musl wouldn't matter. This is why the title doesn't make sense and why your defense of it doesn't make sense either.
You having software that is not only slow but slow because it calls into the default libc has nothing to do with this. Why aren't you mentioning taking it further and linking in a better allocator?
Maybe because it's the same idea but contradicts what you keep trying to say to avoid the actual point, which is that the title is wrong.
If you're going on a long trip and you get better shoes and can walk to your car 25% faster, how much is that going to speed up your trip overall? It will be basically nothing, because you are optimizing something almost irrelevant.
I can use musl and create software that outperforms whatever someone else makes using the default standard library. If this is possible, and I explained why it is in detail, then why would the title be true? Explain that instead of getting upset and avoiding the heart of the discussion with irrelevant tangents about your own legacy programs.
> Every default malloc implementation worked this way about 12 years ago.
Perhaps "default" is doing the heavy lifting here. Glibc malloc was quite bad for a long time, true. But TCmalloc / jemalloc are 21-22 years old, respectively, and jemalloc has been the FreeBSD (released) default malloc implementation for the last 18.
> The solution is and always has been to make larger allocations and use those efficiently.
Having a not-dogshit allocator really doesn't hurt. There's no reason to defend shitty allocator + every application doing manual memory pools on top of it to paper over the bad allocator.
I'm not defending anything, I'm saying it's usually trivial to make allocation time marginal.
+ every application doing manual memory pools
Usually it's simple data structures in flat memory.
If allocation is taking all the time, that's a poorly optimized program with lots of low hanging fruit and a different allocator is not the right fix. It's like having a boat with a hole in the bottom and someone says the solution is a smaller hole.
But TCmalloc / jemalloc are 21-22 years old, respectively, and jemalloc has been the FreeBSD (released) default malloc implementation for the last 18.
jemalloc is also possibly bigger than all of musl. If it was a problem after optimization I would use it and I have in the past, it's just nowhere near as important as minimizing allocations in the first place. OpenBSD uses straight mmap.
There's also a reason this stuff started getting adopted around 20 years ago (I'll add macOS to the pile: it added per-CPU malloc sharding in 2008). It's not just due to overall growth in OS complexity. It's because that's when multicore CPUs were taking off. Before that, the cost of a global lock was far lower.
OpenBSD is straight unconcerned about performance. That's their choice.
> Every default malloc implementation worked this way about 12 years ago.
Yes, it is now 12 years later, and memory allocators are better. The memory allocators of that time were also better than the ones 12 years their prior. That's the point.
> Making lots of small allocations, even from multiple threads then blaming the allocator is a losing strategy. An allocator is only going to be able to mitigate the damage to speed and interactivity.
It's just a reality that musl is measurably worse at multiple threads allocating even in very polite conditions, because it causes lots of contention. If your program allocates in multiple threads, it is probably going to get slower with musl. If you don't want that, other memory allocators will do great even at high allocation rates with more threads. You could write many other data structures that had equally poor behavior under multi-threaded contention by just throwing a lock around everything and calling it a day, and those bad data structures would also cause "damage to speed and interactivity" or whatever. This isn't very hard to understand.
> The compiler should be able to take something with good access patterns and make something fast, especially out of the basic C functions.
I agree, modern compilers are good. But these are extremely common specified functions, they are called everywhere all the time in every C codebase (and that's partially why compilers even recognize these patterns specifically so they can insert optimized routines). Mature implementations that are hand optimized still pay off and also tend to be tuned for various edge cases or quirks that aren't going to come for free from the C compiler either, so it's still work even if you aren't writing assembly for everything or whatever (e.g. uarch dependent codepaths, or optimizations for short strings or whatever).
glibc's AVX2 based memcpy functions have a non-negligible performance impact in at least 1 application I maintain on the order of like 8-ish% vs musl (wall clock). It just has to memcpy/memmove a whole lot. Whether or not that's tolerable is up to debate, but a spade is a spade.
> Performance wise it's unlikely C string functions are actually the bottleneck in a program. Maybe for specific programs a naive memory copy function could benefit from AVX instructions.
I said "backbone", not "bottleneck". They are common functions sprinkled in everywhere throughout every application in every codepath on something like a modern Linux desktop. An inverted callstack flamegraph can show you stuff like this. It is basically no different than compiling your application at -O1 and -O2 with GCC. Does the fact your program get 20% faster from -O2 mean that there were "bottlenecks" the compiler solved? No, there was just performance left on the table by emitting better code.
> "Have to" and "often" are debatable.
Not really. I have to spell it out apparently: actual programs written by normal human programmers do those things, all the time, they exist in and are common in the world, they depend on other code that does that and is common in the world, they run on your desktop and phone and all servers, and they benefit quite a lot from optimized components like memory allocators and string routines and -O2 making their programs faster. This is pretty easy to observe and the means of doing so should be quite obvious, so there's no real debate.
Now whether this fact holds -- whether these programs "have to" do these things or not -- in the imaginary fantasy land people have in their heads where they make up arguments to themselves about how, if every program was written how they liked it, it would be better? That I'm not so sure about, I will admit.
The memory allocators of that time were also better than the ones 12 years their prior. That's the point.
The point is that memory allocation shouldn't be a bottleneck either way. If it is the program needs to be optimized or redesigned. Better allocators give you more slack, they don't solve the problem. If the problem is already solved, then a basic allocator isn't going to make a big performance difference because it isn't the bottleneck.
those bad data structures would also cause "damage to speed and interactivity" or whatever. This isn't very hard to understand.
It depends on how much they are used and how much contention there is. Sometimes putting a mutex around things is fine.
But these are extremely common specified functions, they are called everywhere all the time
Not necessarily, especially for C string functions, but they do get linked in so it's a good thing musl makes them small.
I said "backbone", not "bottleneck".
Then the point is lost, because 'backbone' doesn't mean anything if it works. If it isn't a bottleneck in throughput or latency anywhere then the speed doesn't matter.
The other important thing is that better stuff can be included in pieces as it's needed. The reverse isn't true. If you use a big fat C library, you have a dependency that isn't going to get better.
Not really. I have to spell it out apparently: actual programs written by normal human programmers do those things, all the time,
You spelled it out last time, it's just not true in the sense that programs have to have these functions as bottlenecks. Strings, allocators and memory copying can all be dealt with independently, but again it's rare that strings and allocations really need to be the bottleneck and in those circumstances you probably want more than a different standard library anyway.
in the imaginary fantasy land people have in their heads where they make up arguments to themselves about how, if every program was written how they liked it,
I'm not sure what this is supposed to mean, there is nothing I've said that doesn't make perfect sense. If you want something to go faster you can make it go faster. A better allocator pales in comparison to lifting allocations out of hot loops.
My point is the musl is useful and the disadvantages are easy to work around. I'm not really sure what your point is, do you think people are going to force you to use it?
Your point seems to be that if you use a slow standard library and complain, it's not a problem with the slow standard library because you can just reimplement the slow parts independently.
The problem with your argument is that it's a universal argument against performance. And if an argument is universal, then it doesn't have any information value.
Your point seems to be that if you use a slow standard library and complain, it's not a problem with the slow standard library because you can just reimplement the slow parts independently.
No, this is something that nuanced. The title is wrong because musl isn't going to prevent you from writing fast software.
Whatever benefit there is to a different libc, is absolutely miniscule compared to do actual optimizations like avoiding allocations.
I'll give you real numbers: if you put allocations of short vectors of a dozen floats in a hot loop, when you lift the allocations out your program is going to instantly get about 10x faster. The allocation is no longer going to be the bottleneck, it will be marginal and then a faster allocator isn't going to matter at all.
If someone gets an easy speedup from using a different libc that's great, but the vast majority of time it isn't going to matter and isn't going to be where any real speedups come from. The difference is a small percentage speedup vs orders of magnitude.
The amounts to the title being wrong, using musl or a small standard library just doesn't prevent a program from running fast. It is a tiny difference and even that tiny difference can be changed from things like better allocators which you would do anyway with a standard libc.
Yeah, but there's already plenty written on that topic elsewhere; the OP is making a distinctly different point and everything else in it still applies, I think. Even if you are using a memory safe language -- if you are developing security sensitive software, you need to understand that exploits can now be researched, developed, and deployed in hours (or for stupid bugs, minutes!) instead of days or weeks or months. And this process can now just be massively scaled up with money and compute. It was not like this even 24 months ago.
In theory there is now nothing stopping us (the community/project leaders) from just... Moving the repo somewhere else. We could do that. It would be a pretty sudden alienation of other Google contributors though and probably piss off their legal department -- 99% of them just submit regular fixes like any user, because they are ordinary users of JJ. They just happen to work at Google. It would just be stirring up shit for nothing. It isn't an unthinkable outcome, but it isn't one we're just going to "do" for no reason or because it would make people posting on forums happier.
Realistically a non-ownership-assigning CLA on a non-copyleft Apache 2.0 project like in this case doesn't actually mean anything or confer any power. It's all just paperwork that serves as a legal ass covering mechanism because big companies use lawyers. It's like checking the "Yes I am over 18 years old" box on a website. I say this as someone who hates the stupid CLA bot and am a contributor.
As far as actual leadership goes Google does not "own" anything in that regard, nor the day to day work, nor can it really force any of the community to do anything. There's 1 maintainer from Google out of 9 total and +95% of major contributions don't come from Googlers, ERSC, or even any particular company. They don't contribute most of the code, they don't lead most of the community, they are vastly dwarfed by the community in total size, contribution count, etc. What "ownership" or leverage do they have beyond a Github org in this setup? It's annoying but it isn't the same thing as being able to exercise meaningful levers of power, in my experience, and so most of us are just fine with it. Even if there was some stupid bullshit like a disagreement over implied trademark rights, the community could just rename and move on and Google would have nothing. That is where the real power lies.
reply