Profiling

The Future of Ruby Performance Tooling

The Future of Ruby Performance Tooling

by Aaron Quint

In the presentation titled "The Future of Ruby Performance Tooling," Aaron Quint discusses the evolution of Ruby's performance capabilities, especially with the introduction of Ruby 2.1. He emphasizes the necessity of improving application performance for both user experience and cost-effectiveness at production levels. The talk addresses a variety of performance tools, new features, and personal experiences at Paperless Post while scaling their Ruby applications.

Key Points Discussed:
- Importance of Performance: Performance is vital not only for user experience metrics (like page load times) but also affects operational costs. Quicker applications lead to lower server requirements and resource savings.
- Historical Context: Ruby's development has prioritized developer ease, often at the expense of performance for large applications. However, there has been a recent shift, particularly with increased operator contributions to Ruby’s development.
- Introspection Tools: Ruby now has enhanced introspection APIs which are essential for performance management in large-scale applications.
- Categorization of Tools: Quint likens performance tools to a D&D scoring system, discussing various tools:
- ActiveSupport Notifications: Effective for tracking time for specific code execution, though its detailed tracking can impact performance.
- rblineprof: A line profiler that helps identify performance bottlenecks on a per-line basis within the application code, but is not recommended for production use due to its overhead.
- pp_profiler: Designed for local development, this tool benchmarks execution time and fosters team collaboration by generating readable results.
- StackProf: A sampling profiler ideal for identifying hotspots in applications with minimal performance impact, offering insights through flame graphs.
- Generational Garbage Collection: Recent Ruby updates feature improvements like the ObjectSpace API for memory inspection, enabling developers to address memory leaks and optimize memory usage.

Quint expresses optimism about the future trajectory of Ruby performance tooling, influenced by successful concepts from other languages like Go. He concludes by encouraging developers to focus on effective introspection and utilize various tools at their disposal to enhance application performance. The overall message emphasizes a collective move toward better performance management in Ruby development.

00:00:14.460 Hello, everyone! Can everybody hear me? Yes? No? Thumbs up? I can't tell. Woo! All right. Um, hey everyone.
00:00:22.210 Good morning! I want to thank the GoRuCo organizers, especially NYC Ruby.
00:00:30.160 My first meetup was probably in 2005, which is a long time ago now. This is my first time doing a full-length presentation at GoRuCo. Last year, I gave a short talk, but I dropped my iPhone off a boat, so I think Francis and Josh felt bad and that's why I'm here today.
00:00:41.860 Maybe it's because of something else, but regardless, I want to talk about Ruby performance today.
00:00:50.199 I've spent a lot of time thinking about and working on Ruby performance at Paperless Post. We are a platform for delivering important messages online and offline, and we have a great team of talented designers and developers, as well as really good eaters!
00:01:04.299 Today's agenda is more practical. I've been working hard on some interesting things, and I want to share that practical work with you. But first, let’s start with some philosophy.
00:01:16.360 The reason I want to talk today is that performance matters. This phrase gets repeated often, but not everyone addresses why. When we refer to performance, most people are concerned with user experience metrics, like time to first byte and how quickly pages load.
00:01:28.929 These factors significantly impact user experience on your website. From my experience leading a team and working with our operations team in a scrappy startup, performance is also about dollars and cents.
00:01:41.009 The faster your application runs, the fewer servers you need to operate it, resulting in real cost savings.
00:01:50.199 Unfortunately, Ruby's performance doesn't often get talked about positively. However, since this is a Ruby conference, I shouldn’t have to defend Ruby’s worth.
00:02:00.249 When discussing performance, I'm mainly referring to web applications, whether you're running an iPhone app or something similar.
00:02:13.120 I want to illustrate a typical web app request. Imagine your user, who spends time connecting to your server, while your application builds the page.
00:02:25.870 This typically takes 10 to 30 milliseconds, depending on your Ruby processing time.
00:02:39.310 Once the page is built, time elapses while CSS, JavaScript, and images are downloaded. The time it takes for the user to see anything is marked by a dotted line.
00:02:49.390 As developers and operators, we can control certain aspects like how quickly HTML and assets download.
00:02:58.570 However, the crux of the timing issue lies in how long it takes to generate our page on the server.
00:03:10.570 The bulk of the page generation time usually comes from our application code, a significant portion from the database, and possibly from Rails itself.
00:03:22.670 Where do we start to improve performance? In the past, Ruby has suffered due to a lack of focus on operator needs rather than just developer ease.
00:03:35.690 Initially, many features in Ruby and Rails have focused on development speed and not the performance of the final application.
00:03:48.840 However, we have seen a real shift. Last year, several major operators, particularly from GitHub, were given commit access to Ruby.
00:04:00.140 This shift has spurred efforts to improve Ruby's introspection capabilities, which is essential for improving performance.
00:04:12.570 I'm happy to report that Ruby now has APIs to build tools for introspection, which is particularly valuable for operators of large Ruby applications.
00:04:23.560 Today, I’ll give an overview of Ruby performance tooling and some of the new features we can leverage.
00:04:34.500 I’m excited about the potential improvements in Ruby performance tooling.
00:04:40.350 I want to discuss various tools that can track how your application performs. If you aren't using these tools, you're essentially flying blind.
00:04:50.140 It's important to note that there is no single tool that acts as a silver bullet for fixing all performance issues.
00:04:57.530 The reality is that effective Ruby performance management requires a combination of different tools for various situations.
00:05:04.670 I’ve devised a system to categorize Ruby performance tools using what I liken to a D&D scoring system for performance tools.
00:05:12.350 I'll begin with ActiveSupport Notifications. I like to call these the elves of the Ruby performance landscape.
00:05:20.310 ActiveSupport Notifications, introduced in Rails 3, allows you to publish events and collect metrics.
00:05:27.170 This functionality is not just limited to Rails applications, making it widely usable.
00:05:34.000 It essentially tracks the time for specific blocks of code, giving you a way to benchmark performance.
00:05:40.500 However, the performance impact of using ActiveSupport Notifications can vary depending on the level of detail you want.
00:05:48.120 The more specific you aim to be in tracking actions, the more impact you'll have on performance.
00:05:54.760 For operator ease, it's relatively simple to set up, and the readability of the output hinges on how you format the data.
00:06:01.670 For example, if you generate graphs to visualize the data, it's wonderfully insightful.
00:06:07.540 Overall, it’s very effective for monitoring the 90th percentile of your application's performance.
00:06:14.370 Next, I want to talk about rblineprof, which I refer to as the warrior of performance profiling.
00:06:20.230 This tool, developed by Amon, is a first-class line profiler and stands out because it effectively identifies line-level performance issues.
00:06:28.670 Robust line profiling was something that Ruby had lacked for a long time, but this tool changes that.
00:06:37.650 When you wrap a block of your application code, rblineprof will collect detailed execution times per line.
00:06:45.360 This visibility into each line of code is vital for identifying sections that slow down your application.
00:06:54.780 Like other profiling tools, it's not recommended for use in production due to its overhead.
00:07:00.310 After discussing rblineprof, let’s proceed to pp_profiler, which acts as a wrapper around other profiling tools.
00:07:06.630 PP Profiler can run specific code repeatedly while collecting benchmarks of execution time for both cached and non-cached runs.
00:07:12.840 Because it outputs results in markdown format, it's easy to share the results with the team.
00:07:20.270 This tool is specifically designed for local development and is not suitable for production.
00:07:26.360 By tracking local improvements, such as refactoring code and measuring changes, it fosters collaboration among team members.
00:07:35.320 Finally, I want to highlight StackProf, which I consider to be magical.
00:07:43.560 StackProf is a sampling profiler that allows you to gather performance metrics without impacting application performance significantly.
00:07:48.360 It helps identify hotspots in your application and provides visibility into what methods consume the most time.
00:07:55.070 Brendan Gregg has popularized the concept of flame graphs, which visualize this sampling data effectively.
00:08:00.450 By analyzing these flame graphs, you can see where time is being spent in your application.
00:08:09.270 This is particularly useful for diagnosing systemic issues in production.
00:08:14.520 However, the tool is less effective in revealing explicit details about what is making your code slow.
00:08:23.500 We want to reach a point where we can introspect our production environment effectively.
00:08:30.360 As I mentioned, I've been influenced by concepts I've seen while working with Go tooling.
00:08:39.870 In Go, including middleware in your HTTP server generates performance metrics easily.
00:08:46.720 This has inspired me to think about how we can implement similar functionalities within Ruby.
00:08:55.270 The ability to introspect performance in production is incredibly valuable.
00:09:00.800 By using tools like rbtrace and StackProf, we can achieve significant insights regarding our code.
00:09:06.320 I hope to illustrate how effective introspection can lead to an enhancement in our production environment.
00:09:15.190 I also want to touch upon the new generational garbage collection in Ruby.
00:09:23.580 Recent updates have introduced features like ObjectSpace and the ability to dump memory states.
00:09:30.210 This level of introspection lets us explore object allocations in our applications.
00:09:36.040 By utilizing ObjectSpace's abilities, we can identify memory leaks and optimize the memory footprint of our applications.
00:09:44.570 While this tool is powerful, it can cause performance overhead when used in a production environment.
00:09:52.000 However, it opens a host of opportunities for diagnosing and correcting memory issues.
00:09:57.360 I believe that by combining these approaches, we can bring Ruby performance tooling into a new era.
00:10:06.320 With proper introspection, developers can gain the understanding needed to drive impactful performance improvements.
00:10:13.590 Ultimately, the message I want to convey is that Ruby performance tooling is evolving.
00:10:20.610 And that's crucial, especially as we continue to push for advancements in our Ruby applications.
00:10:27.860 Thank you very much for your time! Here's a link to my GitHub, where you can find some of the projects I've mentioned.
00:10:35.160 If you have any questions or want to discuss further, please find me afterwards. Now that I'm done, I'm looking forward to unwinding!
00:10:43.760 Let’s hang out and chat more about Ruby performance tooling. Thank you!