00:00:10.800
To close the day, our final speaker is none other than the inimitable Aaron Patterson.
00:00:18.080
Woohoo!
00:00:25.000
Aaron is the self-proclaimed ‘fun uncle’ of Ruby on Rails. I think he said cool uncle, yes, sorry I forgot that detail.
00:00:30.960
He is a prototypical Ruby and Rails developer, even though he mainly works with C and Rust these days, and he's an all-around lovely person. Please give a round of applause for Aaron!
00:00:54.600
I love you! Oh, thank you! Thank you, Wayne.
00:01:00.320
Thank you, thank you. Thank you, Andy. I'm not the cool uncle, I’m just here to make that clear; I’m the fun uncle.
00:01:07.200
I want to start off today with a few random facts. The first random fact I want to give you is that Ruby actually uses pseudo-random numbers, meaning it’s not perfectly random.
00:01:18.720
The next fact is that you can use `srand` to control your random numbers, which is useful if you need stable random numbers.
00:01:27.119
My next random fact is that you can instantiate a new random object using the Random class.
00:01:32.280
The reason I wanted to share these random facts today is because I feel like random facts these days are not normally distributed.
00:01:38.320
I'm really happy to be here today; it’s great to be in the Motor City. I heard that this is where Rails engines were invented.
00:01:44.479
I was going to talk about Rails engines but decided instead to reflect on some Active Record reflections.
00:01:51.600
I hope you're all prepared for my coverage—just kidding! I really enjoyed this conference. It was great to see Nadia's opening talk about her company, The StoryGraph.
00:02:04.439
Her presentation was inspiring. While I’m not particularly interested in starting a company, I felt inspired to think about it after her talk.
00:02:12.519
I really enjoyed the way she used graphs to tell the story of her company—a story graph, if you will.
00:02:23.800
Erina's talk was also incredible. I loved hearing stories about the different startups using Ruby on Rails to build successful businesses.
00:02:29.040
It made me feel good hearing these success stories, and I appreciated the feedback she provided on how we can improve Ruby and Rails.
00:02:35.200
I think it's really important that our community is encouraged to be loud about the framework that we use and love.
00:02:43.239
However, I have to admit that some of the feedback was hard for me to take as a member of the Rails Core Team.
00:02:51.600
I also enjoyed John's talk on the profiler. After his presentation, I used his profiler to shave about 10 minutes off this presentation.
00:03:05.840
When he first put up his website, he sent me a direct message saying to check out his P.F.P., and I was extremely confused.
00:03:14.880
It turned out he meant his profiler page. Let's move on.
00:03:20.520
I really enjoyed hack day. It was a ton of fun! I helped some folks add a callback to Active Storage, so we could know when a file had been uploaded.
00:03:32.000
I also helped someone run Lobsters, where we were tracking down a memory leak in his application, which I think is awesome because Lobsters is a Rails application.
00:03:44.520
To reiterate Erina's point about being loud, I want to be loud on this stage about my love for Rails.
00:03:57.120
It’s my very first time in Detroit—my first time in Michigan—and I'm so happy to be here!
00:04:05.200
I tried to do all the local Detroit stuff. I rode the People Mover, and I heard there’s a statue built of our most beloved Ruby linter, RuboCop.
00:04:11.600
And it’s true—there is a RuboCop statue here, though I haven't seen it since it’s locked in someone's garage.
00:04:18.480
I also enjoyed some Detroit-style pizza, which was delicious, and I learned that Coney Island is not in New York!
00:04:27.120
I went to Coney Island and had a Coney Island Hot Dog, which was delicious.
00:04:33.840
There are some things I haven’t experienced yet; I haven't been to a party store, which I’ve heard are all the rage.
00:04:39.960
I also have yet to visit our neighbors to the south—Canada!
00:04:49.360
My name is A. P. and I go by Tender Love online. I started a live stream on YouTube mainly to amortize the cost of my green screen.
00:04:58.000
I’m really proud of this live stream because they don’t just give them to anybody! Please join me for the live stream.
00:05:06.200
Don't forget to like, subscribe, and comment below! It really helps the channel grow.
00:05:16.040
We’re only about 97,000 subscribers, almost there!
00:05:22.720
I mostly stream about Ruby and Rails internals, and I will take requests.
00:05:29.520
If there's anything specific you'd like to learn about regarding Ruby or Rails internals, let me know.
00:05:38.000
I work for a tiny startup called Shopify on the Ruby and Rails infrastructure team.
00:05:45.680
Our team has about 36 people, which I verified by looking at the number of people in the Slack channel, so I’m not very sure!
00:05:55.200
We’re divided into three different teams: the Ruby infrastructure team that focuses on the Ruby language,
00:06:02.760
the Rails infrastructure team that deals with the Rails side of things, and the Ruby DX team focusing on developer experience.
00:06:10.239
You might think it’s a bit weird to have those three teams, but it’s cohesive because developer experience works closely with.
00:06:15.680
We deliver the best experiences possible for developers at Shopify and those outside it.
00:06:22.440
For example, the DX team works on language servers, develops the Ruby LSP, and Rails plugins for it.
00:06:33.600
They also do a lot of work on IRB; any areas where developers interact with Ruby, this team is involved.
00:06:42.560
One great example of collaboration is the new gem called Prism, introduced in Ruby 3.3.
00:06:50.760
This gem allows us to do static analysis of code, get error messages, and perform transformations.
00:06:59.280
I talked a lot about developer experience last year, and while it may seem last year's topic, it is still relevant.
00:07:08.000
This year, I want to discuss specifically the speed of Ruby and Rails.
00:07:16.000
The first thing I want to talk about are some upcoming changes in Rails.
00:07:23.840
First, has anyone heard of the Ruby tag in HTML? A couple folks in the audience!
00:07:31.839
This is just an HTML tag used for pronunciation, particularly displaying kanji characters with accompanying pronunciation text.
00:07:40.520
We’re actually adding a Ruby tag helper to Rails, which is exciting!
00:07:47.040
The first feature I want to discuss is enabling JIT in production by default.
00:07:54.760
In future versions of Rails, we will enable it by default in production environments, and we’re currently using that at work!
00:08:00.800
We're observing about a 15% performance improvement and have heard reports of even better results depending on the workload.
00:08:11.360
If you’re in a non-memory-constrained environment, this can be essentially free performance.
00:08:22.720
To enable it today, just generate this initializer and make sure to copy it into your application.
00:08:31.440
What's nice about this initializer is we wait until after the application has booted to enable, reducing memory usage.
00:08:38.640
With this, we're able to delay the JIT during boot time.
00:08:44.760
The next feature is an option to disable connection caching.
00:08:50.560
It may seem a bit odd, but the purpose is to facilitate migration to a block form to help manage connections better.
00:09:00.760
If that method is used, it will raise an exception to guide users toward the new approach.
00:09:09.360
The reason behind this change caters to the application’s concurrency and parallelism.
00:09:20.000
For example, if we manage our database connections more intelligently, we can reduce the number of open connections.
00:09:30.160
Ruby is on a journey to being more efficient overall. CPU-bound code limitations exist in CRuby due to its single-threaded nature.
00:09:39.760
While IO-bound code can run in parallel, CPU-bound calculations can't be sped up using threads or fibers.
00:09:47.760
If you build a service that calculates Fibonacci numbers, that code will not improve speed using threads or fibers.
00:09:56.760
Instead, consider calling out to another service to avoid CPU-bound blocking.
00:10:05.760
This means using threads to wrap IO will allow your code to run concurrently.
00:10:12.760
Using fiber for IO won’t yield speed benefits as they require cooperative scheduling.
00:10:18.960
For high concurrency, choosing fibers with an appropriate library can be beneficial.
00:10:25.319
I’ll provide guidelines for using threads or fibers based on CPU-bound and IO-bound operations.
00:10:33.919
If you have a CPU-bound problem, refactor your code.
00:10:43.920
For simple database queries, use threads or better yet, the load async method for queries to run in background.
00:10:51.800
If you find yourself managing many connections, use fibers.
00:10:59.840
Next, I want to talk about our work with the Ruby side of things, especially around JIT.
00:11:08.080
In the Rails app we've targeted, we want to see speed improvements for production.
00:11:15.839
In Ruby 3.4, we are working on a register allocator to improve local variable memory usage.
00:11:22.720
By retaining values in registers tightly alongside the CPU, we improve the operation speed.
00:11:30.480
However, most focus isn’t on benchmarks but rather on improving the Rails ecosystem as a whole.
00:11:42.080
A noteworthy achievement is the development of the Protobuf library, leading to significant performance gains.
00:11:49.920
Coming up, our performance claims are nine times faster than Google's Protobuff library.
00:11:56.720
We're continuing to enhance Ruby's capabilities to keep developers within Ruby.
00:12:04.160
Next, I want to elaborate on object shapes, initially introduced in Ruby 3.2.
00:12:13.200
Instance variables stored in arrays are indexed, and object shapes serve to map names to indices.
00:12:22.560
When multiple objects share the same variables, we can increase performance by setting those variables in similar order.
00:12:30.000
To streamline instance variable checks, we introduced inline caches.
00:12:39.520
Checks through caches can improve efficiency by reducing lookups to a minimum.
00:12:48.720
Our work in Ruby 3.3 concerning these caches led to significant gains.
00:12:57.040
We examined cache misses happening from improper query handling or variable naming.
00:13:06.960
The solution was to optimize query structures, leading to improved performance.
00:13:12.240
Our team is excited to apply novel data structures in improving memory management.
00:13:22.480
We introduced a functional red-black tree to give faster lookups and greater efficiency.
00:13:30.160
I appreciate the concern for performance; we strive to optimize every element.
00:13:39.680
Our implementation efforts are building towards a swift Ruby performance future.
00:13:49.360
As we transition into the thoughts about concurrency and CPU rights, do keep in mind the techniques presented.
00:13:58.720
I've delved into many details today about performance, caching, and active handling of IO versus CPU.
00:14:07.920
Thank you for joining me on this performance discussion. It’s inspiring sharing these thoughts with the community.
00:14:15.040
Now I want to wrap up, reflecting on being a Rails developer and the community we have.
00:14:24.880
Having attended RailsConf for over 10 years, I find it rewarding.
00:14:33.600
Today, I believe the best era for Rails development is happening right now!
00:14:41.840
With every iteration of Rails, we grow more efficient and have more fun!
00:14:47.600
While I am sad to see that next year will be the last RailsConf, I look forward to this.
00:14:54.920
It’s a pleasure to be part of such a friendly and enriching community.
00:15:04.000
After today, we can continue engaging in the conversation, looking to future opportunities.
00:15:14.960
Thank you so much for attending; it’s been an honor to present to all of you today!