10 ms·
Ruby 3.3
- ksec 3y agoI think Ruby 3.3 is perhaps one of the most important and feature rich Ruby release in the past 10 years. I never thought Ruby would have a shipping and production ready JIT before Python. And Prism, Lrama, IRB. A lot of these were discussed in previous HN submissions. But one thing that is not mentioned or discussed enough, is Ractor, M:N thread scheduler, Fibre and Async. Especially in the context of Rails. I am wondering if any one are using these features in productions and if you could share any thoughts on the subject.
- rjzzleep 3y agoThe one thing I genuinely don't understand is why there is no single task queue that works across ruby and python. I get that at some point people just started making http based microservices to pass information around, but at the end of the day a simple task queue that has a unified storage format across both is a better way to connect ruby(rails) based with the ml stack. There are probably thousands of custom rabbitmq or redis based private company solutions out there.
- petepete 3y agoThere's beanstalkd, it has a few Python libraries and it works out of the box with ActiveJob via Backburner. https://beanstalkd.github.io/ https://beanstalkd.github.io/
- byroot 3y agoMike Perham (the sidekiq maintainer) also maintains the less well known faktory[0] which is language agnostic and has runners for both Ruby and Python [0] https://github.com/contribsys/faktory https://github.com/contribsys/faktory
- rjzzleep 3y agoThat's awesome. Any idea why he doesn't just supersede Sidekiq with that? I spent quite some time hacking my own solution. I just looked at the source, I guess Mike has been mostly working on both projects on his own for the last 4 years, so Faktory has a lot of features that require the enterprise license. I wonder if he could change the situation it he markets a bit more to the python and more specifically Django community.
- f6v 3y agoBecause people running sidekiq with their Ruby app on production don’t care about cross-language queue. If you pay for Pro or Enterprise you don’t want any major changes that are potentially breaking.
- cactusplant7374 3y agoThe only reason we pay is because the pro version doesn't lose jobs if a worker crashes. You would think that would be a core feature.
- deleted 3y ago[deleted]
- aaronbrethorst 3y agoA man’s gotta eat.
- ckolkey 3y agoSounds like Mike found a good feature that would encourage companies to purchase a license. I have a tremendous admiration for the business he's built.
- cactusplant7374 3y agoYou would think not losing jobs would be a required feature in any job queue software product.
- akvadrako 3y agoBecause it's a rare need and easy to write your own based on postgres or redis. External systems come with a cost, especially if it's more than a library.
- pmontra 3y agoMy customers are using Celery for Python and Sidekiq for Ruby. Those are parts of Django and Rails web apps. Those customers don't mix languages so they don't need workers able to run code in multiple languages. One of them is also using SQS though so we could receive a JSON in a server written in any language, do some processing and return the result. However the database of that app has been "destroyed by design" by using Django's ORM inheritance (my suggestion: never use it) so nothing can interact effectively with it except Python code using the same models. By the way, celery was born as a protocol spec to support multiple languages but never moved past Python. I can't google a quote for that, I remember I saw it years ago in the documentation somewhere.
- rjzzleep 3y agoI can see that it was born that way, but nowadays most job queues say, don't touch the wire protocol, it's not intended to be used directly. I still think Rails has the best ORM design I've ever seen, iterated with practical applications. Django's ORM and migrations are, for lack of a better word, odd. I'm a bit surprised that people here argue that no one using Rails would ever want to interface with other languages. Most big companies do. How can you not interface with python these days. Looks to me like celery might just be the only job queue left like that. Might be worth writing a current ruby en-queuing library for it. Retracting my previous statement about ActiveJob since it would probably be too much effort to execute anything bidirectionally. https://docs.celeryq.dev/en/stable/internals/protocol.html# https://docs.celeryq.dev/en/stable/internals/protocol.html#
- riffraff 3y agoWhat's wrong with Django's orm? Does it have something particularly bad compared to others?
- cdcarter 3y agoI think the poster is specifically referring to using inheritance in Django ORM, where if you had e.g. a model Book and then a model Novel that inherits from it. In python these are modeled as a class inheritance hierarchy, and Django (at least, by default) creates a database table per class in the hierarchy. If you have 3-4 levels of inheritance, that's 3-4 extra joins per query.
- emmelaich 3y agoThere is Perl Directory::Queue / Python dirq which also has implementations in Go, Java, and C. A Ruby implementation would probably not be hard. I don't how much people use this in serious or high performance work but it might be an option.
- jsjohnst 3y ago> The one thing I genuinely don't understand is why there is no single task queue that works across ruby and python. Not sure I can recommend it, but Gearman does fit the bill. There’s client and worker libraries for a dozen languages, including Python3 and Ruby.
- Alifatisk 3y ago> I think Ruby 3.3 is perhaps one of the most important and feature rich Ruby release in the past 10 years. Really? What’s so significant with this release? > But one thing that is not mentioned or discussed enough, is Ractor, M:N thread scheduler, Fibre and Async. Yes! Ractors deserve more highlighting! It’s a huge feature.
- Lio 3y ago> Really? What’s so significant with this release? I think the Prism parser update is a standout highlight for me. This is the start of many new static analysis tools for ruby. It's also significant that RBS type information is starting to be used in IRB autocompletion. Previously RBS has been an interesting experiment but hasn't had much practical use compared to Sorbet. Ruby seems to now have good answers to non-blocking IO (async fibers) and tooling questions (ruby-lsp). We're starting to see YJIT performance improvements starting to compound with more to come too. That all seems significant to me. Thanks to everyone involved.
- rfoo 3y ago> I never thought Ruby would have a shipping and production ready JIT before Python. This is entirely predictable - Ruby does not have a big scientific computing community which happened to depend on every implementation detail of the hosting interpreter.
- byroot 3y agoI don't see how it's relevant given that YJIT didn't cause any compatibility issue whatsoever.
- pjmlp 3y agoPython has a culture that sees writing C libraries as "Python" code, hence why. It is quite common to see "Python" libraries that are just thin bindings layers, they could just as well be "Tcl" libraries for that matter.
- tnecniv 3y agoI should start doing numerical work in TCL and see how long it takes for me to get set to the mad house
- pjmlp 3y agoWell, first step is to create bindings to the same libraries Python uses.
- nerdponx 3y agoThe problem is that Numpy is not in fact anything close to a thin wrapper around BLAS/LAPACK like people seem to think it is. First of all, it contains a ton of custom C code, which to some extent could be extracted to a separate library in theory, but isn't. Second, a lot of that custom code interacts deeply with the Python C API, which historically was very open-ended. Even getting it to work on another implementation of Python was a challenge that took a long time to reach baseline usability. You could forego Numpy and call out to a library like Eigen, but even then you have a huge amount of work ahead to achieve anything resembling feature parity.
- phaedryx 3y agoPrism is interesting. Any Ruby code analysis tools that use it? I've been looking for ways to analyze my code at work.
- alberth 3y agoEvery Christmas, like clockwork, Ruby Lang drops a new release.
- quickthrower2 3y agoIt is a cute thing about Ruby
- mberning 3y agoYou love to see it.
- revskill 3y agoI hope Ruby 4.0 could allow explicit import and avoid implicit, global namespace gem import mechanism like nowsdays.
- t-writescode 3y agoI'm feeling a bit ignorant, but isn't this a Rails thing and not a Ruby thing? I know that for most projects that's a distinction without a difference; but, that may be a decision from the Rails devs and unrelated to what Ruby's devs do? Or I'm speaking out of my ear and completely wrong (and I don't know which :D)
- byroot 3y agoIt's a Ruby thing. Ruby only has a single global namespace, no imports. If anything Rails autoloading (Zeitwerk really) make it much easier to find where constants come from as it enforce a constant name -> file name convention, so all you need is fuzzy file search.
- Calavar 3y agoYou're right, implicit import (autoload) is an opt-in feature. Rails used to use autoload by default as of 3.x/4.x. It's been quite a while since I used Rails, so I'm not sure if this is still the case. Ruby imports have always used a single global namespace. I'm not convinced that this is an issue in practice - it's worked just fine for several other languages.
- lloeki 3y agoThere's a big difference between Rails autoloading and Ruby autoload, in that Rails is implicit and conventional from the constant name plus load paths, whereas Ruby is explicit as one declares where to find each constant.
- hetman 3y agoI mean, only because it's possible to learn to live with doesn't make it pleasant. Especially for managing large projects it can get unwieldy. Most high level languages I can think of have moved away from this approach. I used to be a huge Ruby fan but having exposure to Python where this isn't an issue, life is just easier.
- pgib 3y agoVery much looking forward to upgrading our application to ensure 3.3 compatibility.
- ciconia 3y agoI believe with version 3.3 Ruby is back in a big way! The language focused on developer happiness and derided for its slowness is slow no more. YJIT is an amazing technology, and together with other innovations like object shapes and various GC optimizations, Ruby is becoming seriously fast! Big Ruby shops such as Shopify [1] have been running 3.3 pre-release with YJIT and reporting double digit percentage performance improvements. Personally I'm really excited about Ruby and its future. I can't wait to start working with Ruby 3.3 and using it on my client's production sites... [1] https://railsatscale.com/2023-09-18-ruby-3-3-s-yjit-runs-shopify-s-production-code-15-faster/ https://railsatscale.com/2023-09-18-ruby-3-3-s-yjit-runs-sho... Edit: add percentage to performance improvements.
- IshKebab 3y ago> double digit performance improvements You mean like 10% faster, or 10x faster? Edit: clicked the link; it's 10%. I don't think that's going to make any difference to the perception of Ruby's slowness given that it's on the order of 50-200x slower than "fast" languages like Rust, Java, Go and C++.
- Alifatisk 3y agoI seriously don’t think it’s worth comparing Ruby to languages like C++ and the rest. One is scripting language, the other compiled, the difference is huge already there.
- deleted 3y ago[deleted]
- trealira 3y agoIt may be worth comparing this new JIT to fast implementations of dynamic languages, like LuaJIT or SBCL for Common Lisp (SBCL is an AOT compiler and not a JIT though).
- pdimitar 3y ago> I seriously don’t think it’s worth comparing Ruby to languages like C++ and the rest. It is worth comparing any two languages and ecosystems if they are used for the same things, in this case -- web backends. Anything and everything that has a web backend is a fair game for comparison.
- nextaccountic 3y ago> RUBY_MAX_CPU=n environment variable sets maximum number of N (maximum number of native threads). The default value is 8. Shouldn't the default be the number of logical cores? Like Rust's Tokio and countless other M:N runtimes
- MoOmer 3y agoThat’s an optimization that can be added later, with some nuance. IIRC Go had a similar situation for years; I remember setting GO_MAX_PROCS in my init() or main()!
- Alifatisk 3y agoYeah, setting a hard cap on the maximum cpu count doesn’t feel right? Why not depend on the available cores?
- SkyPuncher 3y agoIt’s a safe choice. Some systems won’t report cores correctly which can lead to reallllllly bad performance.
- nextaccountic 3y agoMaybe make it min(8, available_cores()) or something like that
- captn3m0 3y agoFriendly reminder that Ruby 3.0 will now go EOL in 3 months, so you have 12 weeks to upgrade.
- awestroke 3y agoI don’t think I will.
- pmdr 3y agoThe perfect Christmas gift!
- xpressvideoz 3y ago> Name resolution such as `Socket.getaddrinfo` can now be interrupted. Whenever it needs name resolution, it creates a worker pthread, and executes `getaddrinfo(3)` in it. Do other language runtimes do similar things? Creating a thread sounds too heavy, though it might not matter in practice. As per their own benchmark, the overhead is minimal but still not zero. 10000.times { Addrinfo.getaddrinfo("www.ruby- lang.org", 80) } # Before patch: 2.3 sec. # After ptach: 3.0 sec. 100.times { URI.open("https://www.ruby-lang.org").read } # Before patch: 3.36 sec. # After ptach: 3.40 sec.
- Alifatisk 3y agoWouldn’t a fiber be more lightweight than having to create a new thread?
- byroot 3y agoA fiber doesn't have a dedicated execution context, so it would be just as blocking.
- Alifatisk 3y agoIs there really no other way than creating a whole thread for this?
- viraptor 3y agoYou can use a pure ruby resolver if you want. For example https://github.com/socketry/async-dns https://github.com/socketry/async-dns But that way your sacrificing integration into your system's nsswitch which may want to do something completely different with your requests. You could also query over dbus which can be async https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.resolve1.html https://www.freedesktop.org/software/systemd/man/latest/org.... (if you can depend on systemd)
- byroot 3y agoThere is a few alternatives like getaddrinfo_a(3) but they have other downsides (fork safety concerns). If you want more context, you can read: https://bugs.ruby-lang.org/issues/19430 https://bugs.ruby-lang.org/issues/19430
- 999900000999 3y agoWorth it to learn Ruby if you already know Python and NodeJS ? I find Ruby fascinating yet difficult.
- jitl 3y agoI think Ruby is much better at shell script like tasks and interactive / exploratory programming for system tasks compared to Python or Node. Use it as “better bash” or “better Perl” and it’s worth it. I primarily work in a Typescript codebase, but regularly reach for it as a tool to wrangle log data, semi-structured text, or do regex rewrites of a bunch of files. Ruby is also very fun, probably the most fun language I’ve used regularly. That makes it its own reward.
- callc 3y agoThis is very intriguing, could you please elaborate? I have been looking for a better bash for scripting stuff without all the bash and sh-isms and gotchas.
- ignurant 3y agoSome of the most enlightening books I’ve read when I was first learning Ruby were Text Processing in Ruby, and Building Awesome Command Line Apps in Ruby 2. They each reveal certain features and perspectives that work towards this end, such as text parsing moves, Ruby flags to help you build shell 1-liners you can pipe against, and features with stdio beyond just printing to stdout. Then add in something like Pry or Irb, where you are able to build castles in your sandbox. Most of my data exploration happens in Pry. A final book I’ll toss out is Data Science at the Command Line, in particular the first 40 or so pages. They highlight the amount of tooling that exists that’s just python shell scripts posing as bins. (Ruby of course has every bit of the same potential.) I had always been aware of this, but I found the way it was presented to be very inspirational, and largely transformed how I work with data. A good practical example I use regularly is: I have a project set up that keeps connection strings for ten or so SQL Server DBs that I regularly interact with. I have constants defined to expedite connections. The [Sequel library](https://sequel.jeremyevans.net/ https://sequel.jeremyevans.net/) is absolutely delightful to use. I have a `bin/console` file that sets up a pry session hooking up the default environment and tools I like to work with. Now it’s very easy to find tables with certain names, schemas, containing certain data, certain sprocs, mass update definitions across our entire system. ``` # Something failed, and not everything loaded as you expected # explore explore explore… db::CompetitorPricing.tables db::CompetitorPricing.tables.grep(/^pricing_/) latest = DB::CompetitorPricing.tables.grep(/^pricing_/).map {|table| [table, table.max(:create_ts)} latest = latest.sort_by(&:last) # serialize to csv, or json, or perhaps copy the data into excel: Clipboard.copy latest.map{ _1.join("\t")}.join("\n") ``` Just like with work in the shell, you have a really easy time iteratively exploring the problem and building up your answer. The ability to serialize your data you’ve found, and keep your favorite tools in your pocket feels extremely productive. And of course, all of this can be written in ruby 1-liner shell scripts, or more complex shell scripts to pipe in and out of other tools if desired.
- Exuma 3y agoJust enabled YJIT this morning. Merry CHristmas!
- schneems 3y agoAvailable on Heroku https://devcenter.heroku.com/changelog-items/2772 https://devcenter.heroku.com/changelog-items/2772
- olivierlacan 3y agoThanks Richard.
- schneems 3y agode rien
- mortallywounded 3y agoIt's nice to see improvements to Ruby, but the hype around a ~13% performance boost feels... weird. It looks like a big leap, but when you compare the actual speed to _any_ other language you realize Ruby still has many, many percent to go to even be in the same game.
- byroot 3y agoThis number is from a production workload with a significant chunk of IOs. If you look at CPU bound micro-benchmarks like most similar announcements uses, you easily get into the 3x territory: https://railsatscale.com/2023-12-04-ruby-3-3-s-yjit-faster-while-using-less-memory/ https://railsatscale.com/2023-12-04-ruby-3-3-s-yjit-faster-w...
- alberth 3y ago> “get into the 3x territory” Where are you seeing 3x improvement? Because even this graph from your article doesn’t show that, unless you’re comparing JIT vs non-JIT. But JIT has existed for awhile now (not new in 3.3). https://railsatscale.com/2023-12-04-ruby-3-3-s-yjit-faster-while-using-less-memory/images/bars_optcarrot.png https://railsatscale.com/2023-12-04-ruby-3-3-s-yjit-faster-w...
- byroot 3y agoIn the yjit-bench suite, there are a number of micro benchmarks that had a 2-3x gain between 3.2 and 3.3: https://speed.yjit.org/stats-timeline.html https://speed.yjit.org/stats-timeline.html But my point is that the YJIT team never really communicate numbers from synthetic benchmarks, it's very focused on real world workloads. Synthetic benchmarks are used internally, but mostly to optimize a specific pattern that was identified as a common hotspot. All this to say this figure you quote is not to be directly compared to many similar announcements from other projects or benchmark suites. Now if you still think it's not good enough, I encourage you to try your hand at it to see how much of an accomplishment that really is.
- nixpulvis 3y agoAnyone have a link to some good examples of using Prism? I was disappointed to not really see anything other than the “Notable API” from this release page.
- st0012 3y agoThese are the Ruby libraries that already adopted Prism: https://rubygems.org/gems/prism/reverse_dependencies https://rubygems.org/gems/prism/reverse_dependencies
- DanielKehoe 3y agoLooks good. There's a new IRB, the interactive Ruby interpreter, with better autocompletion and debugging. Most of the Ruby 3.3 changes will lead to improved developer tooling. The language API is largely unchanged and consistent with previous releases. I wrote a guide [1] for the update to Ruby 3.3, with notes for each of the various version managers. [1] https://mac.install.guide/ruby/update.html https://mac.install.guide/ruby/update.html Just curious, which version manager would you recommend? Previously I recommended asdf, frum, or chruby.
- azuanrb 3y agoI don't have any issue with rbenv or asdf. Using both in local and production environment.