3,991 karma · joined October 8, 2009
Working on ZJIT & TruffleRuby at Shopify.
TruffleRuby applies many of these same techniques to Ruby to great effect. Fortunately, most applications stabilize at some point and a JIT compiler can do wonders. E.g., TruffleRuby has had zero-overhead metaprogramming for a decade now[1]. But, these optimizations incur trade-offs. TruffleRuby has a Ruby core library mostly written in Ruby to help optimization, but that means the interpreter takes a performance hit. The CRuby VM has most of its core library written in C because the team favors having a fast interpreter with low overhead, which is great, but means much of the core library can't be JIT compiled alongside an application.
I think the real answer why the CRuby VM lags behind the JVM is more pedestrian: there's been orders of magnitude more investment made into the JVM than any Ruby VM. Sun and then Oracle have hired world class VM developers and researchers to work on multiple JIT compilers, multiple GC implementations, fast tooling, a standard memory model, world-class concurrency library, and so on. OpenJDK sees heavy investment by many others, too (RedHat probably leading the charge). And then you have other vendors advancing the state of the art with alternative VM implementations (Azul, IBM, Amazon, etc.).
Ruby as a language has seen loads of research done on compilation and alternative VMs [2], but the CRuby VM itself hasn't seen anything close to OpenJDK's investment. That's not to say there isn't excellent work being done to improve the CRuby VM. But, production VMs are large, complex projects and not the sort of thing easily moved by a volunteer working nights and weekends. More investment by companies using Ruby would help close the gap.
[1] -- https://chrisseaton.com/rubytruffle/pldi15-metaprogramming/p... (FYI, the paper refers to JRuby+Truffle, which is TruffleRuby's old name).
[2] -- https://ruby-compilers.com/
We've been shipping TruffleRuby as native image builds for years. Other Truffle languages have as well. And it's been quite popular with microservice frameworks. Recently I saw someone on the GraalVM Slack say they AOT compiled a large JavaFX application.
It's work, but probably far less than a rewrite in another language and the tooling is getting better. Obviously I can't speak to your experience, but if you haven't looked at it in a while it might be worth giving newer releases a shot.
https://www.graalvm.org/jdk24/reference-manual/native-image/
There’s a new LTS release with improvements coming out next week.
I could use one repo for work and one for personal and live with the mess of useless files, but I like the cleanliness and having simple git histories. I also don’t have to have conditional statements all over the place.
I get the point you're making, but it really seems like we haven't remembered. We've worked ourselves back into one juggernaut owning most of the web browser space and then collectively acted surprised when they started flexing their muscles. I encounter sites that only run in Chrome the same way I had sites that only ran in IE 6. It seems to me we're doomed to repeat history as long as that path is easier or more profitable.
I don't personally get too attached to devices I purchase or begrudge others for what they buy so, I'm curious what made them "cringe hardware" in your opinion. Adoption aside, they looked like pretty compelling devices to me. Is this a case of buying anything that isn't Apple isn't cool? Or is there something deeper there?
Contributors must sign a Contributor License Agreement (CLA) before a contribution will be merged. The CLA signers gave Elastic the right to change licenses, among others, when they signed the agreement. Consequently, Elastic doesn't need to get individual sign-off from each contributor before changing the project license. The code wasn't based on copyleft license, so there's no compulsion to continue using the same licensing terms for all future distributions. That's a motivating factor for many CLAs. If you made a contribution prior to the introduction of the CLA then things get murkier.
The original licensing decision was made well before the formation of Elastic the company. Maybe Shay didn't quite give it the full consideration. I don't know him super well, but like most developers starting open source projects, I don't think he has a legal background. I confess to a certain about of naivety, thinking that contributors would adhere to the spirit of contribution rather than the absolute letter of the license. I don't think it's unreasonable to have societal expectations above and beyond the legal requirements.
I've been doing open source for ~25 years and it appears to me there's been a distinct shift in how companies approach open source. I feel like what I started with was almost a eutopic ideal and now I'm expected to just do free support work for companies that don't want to pay anything to anyone. I don't see any problem with devs realizing their mistake or changing their mind and updating the license accordingly. For my part, I used to use ASLv2 for everything and now I default to AGPL.
> You can't have it both ways. Why do you think people drop these projects the moment these corporations decide to pull the rug from under their userbase?
Just like you have no legal obligations above what the license says, they have no legal obligations to make their work available under the license you want. It's open source, so feel free to take the commit from version before the license change. Of course, it turns out it's quite a bit messier to have two incompatible versions floating around, but as long as we're limiting ourselves to legal requirements that's a non-issue.
The most obvious reason these projects get dropped after a license change is because they now use a license that needs to be reviewed. It's a lot easier to justify spending on a new AWS service than it is getting a new license approved. But, that was more or less happening anyway. If you're already on AWS it's easier to add a new service than pay for hosting a service with a third party. I don't particularly fault Elastic for not wanting to be Amazon's R & D arm and support team.
We have a lot of systems and infrastructure in place that only mostly work because both parties hold up their own end of an unspoken agreement. Large tech companies have decided they can save money by breaking breaking away from that and just sticking to the letter of the license text. Legally, they have that right, but the other parties have predictably responded. I think what it really shows is our licenses don't fit all scenarios. Maybe I'm okay with individuals and companies with a market cap < $1T using the software under terms akin to open source but don't want to be a de facto employee for a large company reselling my software. We're well past the point of open source being about software freedom.
Most of these projects start off as a developer choosing a license without having the legal background to truly assess it and then they run into an 800 lbs. gorilla with loads of in-house counsel. Blaming them for not thinking it all the way through or realizing the implication of their license choice seems to me counter-productive. Okay, so they made a mistake. What now? They don't want to continue working under the framework where they feel being taken advantage of. I don't think they should be obligated to continue doing so because all of the non-Amazon folks don't want to incur the headache of forking. I'd love to see some of that ire aimed at the company willing to break the illusion to make some extra money than the folks that have freely given away their work for years.
I’m not trying to correct you. It’s just a sequence of events I’ve seen play out repeatedly and I’m not sure if there’s a solution. Most recently I’ve seen it with Bambu Lab locking down their 3D printers. Prior to that Autodesk yanking the Fusion 360 enthusiast licenses.
Maybe there isn’t a solution. There’s a lot of UX work that isn’t fun to do and so it’s hard to get volunteers to do it. It’s hard to do product management in a distributed group of volunteers in general. So, companies that can afford to bankroll projects often gain traction with performance or usability gains and suck away attention and funding from open source options. Then when they amass enough of the user base they flip the switch and now folks are stuck. The cost of changing is often prohibitively high and the OSS option is generally far behind at that point.
I think people are bad at thinking longer term. Or maybe they just prefer immediate gratification. In any event, absent a shift in human behavior I expect we’ll see this sort of situation to continue to play out. It’d just be nice if folks were less antagonistic about it when those concerned raise that alarm.
Kagi rolled out a free feature to its existing customers without increasing the price of their plans. The limits of that plan seem quite generous, as well. The only way I can make sense of the OP's post is that the OP wants the Kagi subscription price to decrease. Perhaps that's fair, but it doesn't make any sense here because you're strictly getting more for your money. If you're paying $10/month for a subscription, yesterday you couldn't use Assistant and today you can for the same $10/month. Placing a cap on how much you can use seems quite reasonable given the service costs money to operate. If you choose not use it, you're no worse than you were yesterday... you can happily go about using the search service you were already paying for.
Is the problem that the free usage isn't unlimited? Is it that not using the free service doesn't reduce the search price? Or is it that those using Assistant more than you appear to be getting more value for their money? I'm not trying to be dense, but I really don't see what's even remotely controversial about this announcement.
Lately, every subscription I have is increasing the fee without giving me anything. Kagi is giving me something extra without charging me any more money. I'm sure the nefarious intention is to make their service more attractive to non-subscribers and grow their userbase, but interests can align.
If you want metered billing, there's no shortage of AI services that offer that option. Kagi even offers one by way of the FastGPT. You can also pay to use their search API if you don't think the subscription is worthwhile. You can cobble something together with Open WebUI pretty easily.
I have Kagi Family plan for my household. I've been paying for the Ultimate upgrade for my account in order to access Assistant, but given how infrequently others in my family would use it, it never made sense to upgrade them. Still, it would have been convenient if they could occasionally access Assistant. And now they can. And my bill didn't increase. And they're being incredibly transparent about what the limits are and why they're there. I'm a really happy customer today.
I think founders are doing themselves a serious disservice. I loved working at startups but it’s just not worth it in most cases. The trade-off was always take lower salary for a chance at making big money and repeatedly investors and founders perform a rug pull.
Blaming employees for a change in the gentleman’s agreement is certainly one way to look at it. But, it sure feels exploitive, especially for younger folks that haven’t yet been burned by it. If founders keep doing it… well good luck finding anyone willing to work at their startup.
Abuse of extensions was certainly a problem with IE. But, Google was also happy to use IE controls for Google Toolbar and other functionality. It irks me when a company/tool makes use of another's more permissive policies/APIs in order to gain a foothold and then restricts others from doing the same with its products. It feels like pulling the ladder up behind you.
You said "... why do people believe the rich don't pay their fair share when the top 10% pay almost 3/4 of the taxes... "
I'm suggesting talking about the top 10% is misleading because when people talk about the rich not paying their fair share, they're not talking about the master electrician in your home town that broke $180k working overtime. You conflated the rich with the top 10%, but your grouping includes a whole lot of people that most of us wouldn't consider rich.
To answer your question about why people believe the rich don't pay their fair share, you either need to look at a different figure than the top 10% (which invalidates the 3/4 of the taxes portion) or you need to say everyone (including married couples filing jointly) making $178k MAGI is rich. I don't think people at large agree with the latter, so the rest of your question is premised on the wrong set of numbers. That may answer the question you posed initially.
But, I agree that this conversation is no longer productive. If my mind seems made up it’s because I’ve done extensive work on three Ruby VMs, two Ruby JIT compilers, and run large Rails applications in production. My assertions on Ruby performance are pretty well-informed. It feels to me like you’re talking past most of points to tell me I’m wrong. Without addressing any of my points at more than a superficial, seemingly flippant, manner it’s hard to have a productive discussion.
Leading off with “I think many people do not understand Unix processes and don’t realizing how rare it is to need bindings, ffi, and many libraries” is a pretty bold claim. It’s of course possible the entire Ruby community is doing things wrong. It’s also possible there are aspects of the problem that haven’t been considered. But, I was hopeful a bold claim would have data to support it.
I care a lot about Ruby performance and if you’ve got novel ideas that can work in practice I’d love to hear them. But, this works best with concrete implementations. If you have benchmarks that show I’m wrong I’ll be happy to concede the entire thread.
My mistake. I assumed the conversation was relevant to the post. I hadn't realized the topic had diverged.
> I think you’re vastly overestimating the fork/exec overhead on Linux. If your hot path is this hot you better not be calling Ruby functions.
We're talking about running a Ruby application. Let's use Rails to make it more concrete. That's going to be a lot of Ruby on the hot path. Avoiding that is tantamount to rewriting the application in another language. But, Ruby on the hot path can be fast, particularly when JIT compiled. And that's going to be faster than spawning a new process. The article even demonstrates this showing hot `String#bytesize` is faster than all other options. That's not to say writing a program in C is going to be slower than Ruby, but rather that integrating Ruby and C, which will involve translation of data types, is going to favor being written in Ruby. And, of course, the implementation of `String#bytesize` is in C anyway, but we don't have to deal with the overhead of context switching.
> You’re already doing it. Do you have a database? Nginx? Me cached? Imagemagick? Do you use containers?
All of those things ship as packages and are trivial to install. I don't need to compile anything. Packaging this theoretical application in a container out of band isn't going to help. Now, I need to `docker exec` on my hot path? No, that won't work either. So, instead, I need to add an explicit compilation step to what is otherwise a case of SCPing files to the target machine. I need to add a new task whether in the Dockerfile or in Rake to build an application to shell out to. At least with a native extension packaged as a gem there's a standard mechanism for building C applications.
There's no getting around that this complicates the build. I'm not sure why that's debatable: not having to do all of that is easier than doing it.
> Consider the alternative: is the ideal world the one where all software is available as a ruby package?
I'm not saying we should rewrite everything in the world in Ruby. But, yes, for a Ruby application the ideal world is one in which all code is written in Ruby. It's the simplest option and gives a JIT compiler the most context for making optimization decisions. I'm not interested in using Ruby as a glue language for executing C applications in response to a routed Rails request. At that point I may as well use something other than Ruby and Rails.
I never worked at Twitter, but based on the timeline it seems very likely they were running on the old Ruby 1.8.x line, which was a pure AST interpreter. The VM is now a bytecode interpreter that has been optimized over the intervening years. The GC is considerably more robust. There's a very fast JIT compiler included. Many libraries have been optimized and bugs squashed.
If your concern is Rails, please note that also has seen ongoing development and is more performant, more robust, and I'd say better architected. I'm not even sure it was thread-safe when Twitter was running on it.
You don't have to like Ruby or Rails, but you're really working off old data. I'm sure there's a breaking point in there somewhere, but I very much doubt most apps will hit in before going bust.
I suppose if you could statically determine all of the bindings at boot up you could write a stub and insert into the method table. But, that still would happen at runtime, making it JIT. And it wouldn't be able to adapt to the types flowing through the system, so it'd have to be conservative in what it accepts or what it optimizes, which is what libffi already does today. The AOT approach is to write a native extension.
I'm with you here.
> ...many people do not understand Unix processes and don’t realizing how rare it is to need bindings, ffi, and many libraries
But, this is a much stronger claim.
I can't tell if you're making a meta point or addressing something in the Ruby ecosystem. I mentioned database library bindings because that's far and away the most common usage in the Ruby ecosystem, particularly because of its frequent adoption for web applications.
The author is advocating for not using native code at all if you can avoid it. Keep as much code in Ruby as you can and let the JIT optimize it. But, if you do need bindings, it'd be great if you didn't have to write a native extension. There are a lot of ways to shoot yourself in the foot and they complicate the build pipeline. However, historically, FFI has been much slower than writing a native extension. The point of this post is to explore a way to speed up FFI in the cases where you need it.
It needs to be taken on faith that the author is doing this work because he either has performance sensitive code or needs to work with a library. Spawning a new process in that case is going to be slower than any of the options explored in the post. Writing and distributing a C/C++/Zig/Rust/Go application as part of a Rails app is a big hammer to swing and complicates deployments (a big part of the reason to move away from native extensions). It's possible the author is just complicating things unnecessarily, but he's demonstrated a clear mastery of the technologies involved so I'm willing to give him the benefit of the doubt.
A frequent critique of Ruby is that it's slow. Spawning processes for operations on the hot path isn't going to help that perception. I agree there are cases where shelling out makes sense. E.g., spawning out to use ImageMagick has proven to be a better approach than using bindings when I want to make image thumbnails. But, those are typically handled in asynchronous jobs. I'm all for anything we can do to speed up the hot path and it's remarkable how much performance was easily picked up.
If you're looking for static analysis in general, please note that there are mature tools available. Rubocop¹ is probably the most popular and allows for linting and code formatting. Brakeman² is a vulnerability scanner for Rails. Sorbet³ is a static type checker.
The tooling is there if you want to try things out. But, if you want a statically typed language then that's a debate that's been going since the dawn of programming language design. I doubt it's going to get resolved in this thread.
¹ - https://github.com/rubocop/rubocop