Benchmarking helps you measure how well your app performs. It's not just about speed - there are other important factors too. Let's look at what to measure and how:
Speed
- Use a timer to track how long different parts of your app take to run
- Compare these times as you make changes to see if you're getting faster
Ruby has a built-in Benchmark module:
require 'benchmark'
time = Benchmark.measure do
# Your code here
end
puts "Execution time: #{time.real} seconds"
Memory Usage
- Check how much RAM your app uses
- Look for memory leaks (when your app doesn't free up memory it no longer needs)
- Tools like Task Manager (Windows) or Activity Monitor (Mac) can help
For memory profiling in Ruby, you can use the memory_profiler https://github.com/SamSaffron/memory_profiler gem:
gem install memory_profiler
require 'memory_profiler'
report = MemoryProfiler.report do
# Your code here
end
report.pretty_print
Garbage Collection
Ruby's Garbage Collection automatically frees memory by removing objects no longer in use. It uses a mark-and-sweep algorithm to identify and delete unreferenced objects, helping manage memory efficiently without manual intervention from developers.
GC::Profiler.enable
# Your code here
GC::Profiler.report
GC::Profiler.disable
Network Performance
- Measure how much data your app sends and receives
- Time how long network operations take
- Use built-in developer tools in web browsers for web apps
You can use the net/http library and benchmark it:
require 'benchmark'
require 'net/http'
time = Benchmark.measure do
response = Net::HTTP.get_response(URI('https://example.com'))
puts "Data received: #{response.body.length} bytes"
end
puts "Response time: #{time.real} seconds"
For API calls or external service requests, use the httplog https://github.com/trusche/httplog gem. It will log all HTTP requests made by your application.
Disk Input/Output (I/O)
- Track how fast your app reads from and writes to the hard drive
- Count how often your app accesses the disk
- Many programming languages have libraries to help measure this
Here's an example of measuring file read performance:
require 'benchmark'
time = Benchmark.measure do
content = File.read('large_file.txt')
puts "File size: #{content.length} bytes"
end
puts "Read time: #{time.real} seconds"
CPU Usage
- Monitor how much of the computer's processing power your app uses
- High CPU usage can slow down the whole system
You can use the sys-cpu https://github.com/djberg96/sys-cpu gem:
gem install sys-cpu
require 'sys/cpu'
before = Sys::CPU.load_avg[0]
# Your code here
after = Sys::CPU.load_avg[0]
puts "CPU usage change: #{after - before}"
Request Benchmarking
Use Apache Bench (ab) https://httpd.apache.org/docs/2.4/programs/ab.html or wrk https://github.com/wg/wrk for load testing. For example:
ab -n 1000 -c 10 http://localhost:3000/
This sends 1000 requests with 10 concurrent users.
Other gems
status_page
If you're using Sidekiq, it provides built-in analytics. For other job processors, consider using the status_page https://github.com/rails-engine/status-page gem. The following services are currently supported:
- DB
- Cache
- Redis
- Sidekiq
- Resque
stackprof
We use stackprof https://rubygems.org/gems/stackprof to identify performance bottlenecks in Ruby code. It profiles the application, showing which methods consume the most CPU time or memory. This helps pinpoint slow parts of the code for optimization, improving overall application performance.
Tips for Benchmarking
- Test your app under normal conditions and heavy load (Keep Your Site Speedy: Essential High-Traffic Website Optimization Tips https://vulehuan.com/en/blog/2024/7/keep-your-site-speedy-essential-hightraffic-website-optimization-tips-66890fbef0915ca45912b8df.html)
- Compare your results to previous versions of your app
- Use specialized benchmarking tools for more detailed analysis
- For comprehensive benchmarking: You can use the benchmark-ips https://github.com/evanphx/benchmark-ips gem for more detailed benchmarking. It automatically determines the data points for testing our code, so we can focus on the results instead of guessing iteration counts as we do with the traditional Benchmark library.
- Overall Application Performance: Use the rack-mini-profiler https://github.com/MiniProfiler/rack-mini-profiler gem. It will add a speed badge to your pages and provide insights on SQL queries, view render times, and more.
- SQL Query Performance: Rails has built-in query logging. In development, you'll see query times in your server log. For more detailed analysis, use the bullet https://vulehuan.com/en/blog/2024/6/stop-website-slowdowns-identify-fix-n1-queries-with-gem-bullet-667a5f57d57f3511fdf8e376.html gem to identify N+1 queries
- ruby-prof https://ruby-prof.github.io/ is helpful if your program is slow and you don't know why. It can help you track down methods that are either slow, allocate a large number of objects or allocate objects with high memory usage. Often times the results will be surprising - when profiling what you think you know almost always turns out to be wrong.
Remember to only use these tools in development or staging environments, as they can impact performance in production.
For a comprehensive approach, you might create a dedicated benchmarking environment that mirrors your production setup, and run these tools there to get the most accurate results.
