Ruby Logo

TruffleRuby - High-Performance Ruby on GraalVM

Explore TruffleRuby, Oracle's high-performance Ruby implementation built on GraalVM, designed for maximum optimization and speed.

Home Ruby TruffleRuby - High-Performance Ruby on GraalVM

TruffleRuby - High-Performance Ruby on GraalVM

Explore TruffleRuby, Oracle's high-performance Ruby implementation built on GraalVM, designed for maximum optimization and speed.

What is TruffleRuby?

TruffleRuby is Oracle's high-performance Ruby implementation built on GraalVM, focusing on maximum execution speed and advanced optimization.

Key Characteristics

  • GraalVM Foundation: Built on Oracle's polyglot virtual machine
  • High Performance: Designed for maximum execution speed
  • Advanced JIT: Sophisticated just-in-time compilation
  • Native Images: Compile Ruby to native executables
  • Polyglot Support: Interoperability with other GraalVM languages
  • Research-Driven: Based on cutting-edge VM research

GraalVM Foundation

GraalVM is Oracle's universal virtual machine that supports multiple programming languages with shared runtime optimizations.

GraalVM Architecture

  • Truffle Framework: Language implementation framework
  • Graal Compiler: Advanced JIT compiler written in Java
  • Substrate VM: Ahead-of-time compilation for native images
  • Polyglot Engine: Cross-language interoperability

Supported Languages

• Ruby (TruffleRuby)
• JavaScript (GraalJS)
• Python (GraalPy)
• Java (HotSpot)
• R (FastR)
• LLVM (Sulong)
• WebAssembly
• Scala, Kotlin

Installation & Setup

GraalVM Installation

# Download GraalVM Community Edition
# https://www.graalvm.org/downloads/

# macOS with Homebrew
brew install --cask graalvm/tap/graalvm-ce-java17

# Set JAVA_HOME
export JAVA_HOME=/Library/Java/JavaVirtualMachines/graalvm-ce-java17-22.3.0/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH

# Install TruffleRuby
gu install ruby

# Verify installation
ruby --version
# truffleruby 22.3.0, like ruby 3.0.4, GraalVM CE Native [x86_64-darwin]

Using with rbenv/RVM

# Using rbenv
rbenv install truffleruby-22.3.0
rbenv global truffleruby-22.3.0

# Using RVM
rvm install truffleruby-22.3.0
rvm use truffleruby-22.3.0

# Check Ruby engine
puts RUBY_ENGINE        # "truffleruby"
puts RUBY_ENGINE_VERSION # "22.3.0"
puts RUBY_VERSION       # "3.0.4"

Docker Setup

# Dockerfile for TruffleRuby
FROM ghcr.io/graalvm/graalvm-ce:ol8-java17-22.3.0

RUN gu install ruby

WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install

COPY . .
CMD ["ruby", "app.rb"]

Performance Characteristics

Peak Performance

  • Exceptional Speed: Can be 10-100x faster than MRI for optimizable code
  • Advanced Optimizations: Sophisticated inlining, escape analysis
  • Speculative Optimization: Adaptive compilation based on runtime behavior
  • Partial Evaluation: Truffle framework optimizations

Warmup Considerations

  • Slow Startup: Can take 30+ seconds to reach peak performance
  • Memory Usage: Higher memory consumption during warmup
  • JIT Compilation: Requires sustained execution for optimization
  • Profiling Overhead: Initial execution includes profiling costs

Benchmark Example

# Fibonacci benchmark showing warmup effect
def fibonacci(n)
  return n if n <= 1
  fibonacci(n - 1) + fibonacci(n - 2)
end

# Cold performance (first run)
start_time = Time.now
fibonacci(35)
cold_time = Time.now - start_time

# Warm up (run multiple times)
10.times { fibonacci(35) }

# Warm performance
start_time = Time.now
fibonacci(35)
warm_time = Time.now - start_time

puts "Cold: #{cold_time}s, Warm: #{warm_time}s"
# TruffleRuby shows dramatic improvement after warmup

Optimizations & Tuning

JVM Options for Performance

# Optimize for peak performance
ruby --jvm.Xmx8g --jvm.XX:+UseG1GC --engine.Mode=latency script.rb

# Faster warmup (at cost of peak performance)
ruby --engine.Mode=throughput script.rb

# Enable experimental optimizations
ruby --experimental-options --engine.Inlining=true script.rb

# Memory settings
ruby --jvm.Xms2g --jvm.Xmx8g --jvm.XX:+UseG1GC script.rb

Compilation Thresholds

# Control when compilation occurs
ruby --engine.CompilationThreshold=100 script.rb  # Default: 1000

# Immediate compilation (for long-running processes)
ruby --engine.CompilationThreshold=1 script.rb

# Disable compilation for debugging
ruby --engine.Compilation=false script.rb

# Show compilation activity
ruby --engine.TraceCompilation=true script.rb

Profiling and Analysis

# CPU profiling
ruby --cpusampler script.rb

# Memory profiling
ruby --memtracer script.rb

# Compilation profiling
ruby --engine.TraceCompilation=true \
     --engine.TraceCompilationDetails=true script.rb

# Generate IGV graphs for analysis
ruby --dump.Truffle=true script.rb

Native Image Compilation

Native Images: Compile Ruby code to standalone native executables with instant startup and lower memory usage.

Creating Native Images

# Install native-image component
gu install native-image

# Compile Ruby script to native executable
ruby --native --output=myapp script.rb

# Advanced native image options
ruby --native \
     --output=myapp \
     --vm.XX:+UseG1GC \
     --vm.Xmx2g \
     script.rb

# Run the native executable
./myapp

Native Image Benefits

  • Instant Startup: No JVM startup overhead
  • Lower Memory: Reduced memory footprint
  • Self-Contained: No need for Ruby/JVM installation
  • Cloud-Native: Ideal for serverless and containers

Native Image Limitations

  • No JIT: No runtime optimization (peak performance lower)
  • Ahead-of-Time: All code paths must be known at build time
  • Reflection Limitations: Dynamic features may not work
  • Build Time: Compilation can take several minutes

Polyglot Programming

TruffleRuby enables seamless interoperability with other GraalVM languages in the same runtime.

Ruby + JavaScript

# Load JavaScript code from Ruby
js_code = %{
  function fibonacci(n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
  }
  fibonacci;
}

# Execute JavaScript and get function
js_fibonacci = Polyglot.eval('js', js_code)

# Call JavaScript function from Ruby
result = js_fibonacci.call(10)
puts result  # Uses fast JavaScript implementation

Ruby + Python

# Use Python libraries from Ruby
numpy = Polyglot.eval('python', 'import numpy; numpy')

# Create numpy array
array = numpy.array([1, 2, 3, 4, 5])

# Call numpy functions
mean_value = numpy.mean(array)
puts "Mean: #{mean_value}"

# Convert between Ruby and Python objects
ruby_array = [1, 2, 3]
python_list = Polyglot.eval('python', 'list')(ruby_array)

Language Interop Benefits

  • Best Tool for Job: Use optimal language for each task
  • Library Access: Access ecosystems from other languages
  • Shared Optimization: Cross-language optimizations
  • Zero-Copy: Share objects between languages efficiently

C Extension Compatibility

LLVM Sulong Support

TruffleRuby can run C extensions through LLVM Sulong, providing compatibility with many native gems.

# Install sulong component
gu install llvm-toolchain

# Enable native extensions
ruby --experimental-options --llvm script.rb

# Install gems with C extensions
gem install json  # Works with Sulong
gem install nokogiri  # May require configuration

Compatibility Status

✓ Supported:
  • json
  • msgpack
  • ffi
  • pg (with setup)
⚠ Limited:
  • nokogiri
  • mysql2
  • openssl
  • Complex C++ extensions

Alternative Approaches

  • Pure Ruby Alternatives: Use Ruby implementations when available
  • Java Alternatives: Leverage Java libraries for similar functionality
  • Polyglot Solutions: Use other GraalVM languages
  • FFI: Use Foreign Function Interface for native libraries

Development & Debugging

Debugging Tools

# Enable debugging
ruby --inspect script.rb

# Use Chrome DevTools for debugging
# 1. Run with --inspect
# 2. Open chrome://inspect in Chrome
# 3. Connect to remote target

# Traditional debugging
require 'debug'
binding.break

# Performance debugging
ruby --cpusampler --cpusampler.Output=json script.rb

VSCode Integration

# .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "TruffleRuby Debug",
      "type": "node",
      "request": "launch",
      "program": "${workspaceFolder}/script.rb",
      "runtimeExecutable": "ruby",
      "runtimeArgs": ["--inspect"],
      "port": 9229,
      "console": "integratedTerminal"
    }
  ]
}

IGV (Ideal Graph Visualizer)

# Generate compilation graphs for analysis
ruby --dump.Truffle=true \
     --engine.TraceCompilation=true \
     script.rb

# Download IGV from Oracle
# Load generated .bgv files to visualize optimizations
# Understand how Truffle optimizes your code

TruffleRuby Best Practices

Performance Optimization

  • Long-Running Processes: Design for sustained execution
  • Avoid Dynamic Code: Minimize eval, define_method in hot paths
  • Profile and Measure: Use built-in profiling tools
  • Warm-Up Strategy: Plan for JIT compilation time

Memory Management

  • Heap Sizing: Set appropriate -Xmx values
  • GC Selection: Choose G1GC for large heaps
  • Monitor Usage: Use JVM monitoring tools
  • Object Allocation: Minimize unnecessary object creation

Deployment Considerations

  • Container Sizing: Account for warmup resource usage
  • Health Checks: Allow time for warmup before serving traffic
  • Native Images: Consider for fast startup requirements
  • Testing: Test performance under realistic workloads

When to Choose TruffleRuby

Perfect For

  • CPU-Intensive Applications: Mathematical computing, algorithms
  • Long-Running Services: Background processors, daemons
  • High-Performance APIs: Need maximum throughput
  • Polyglot Applications: Integrating multiple languages
  • Research and Experimentation: Exploring language optimization
  • Cloud-Native (Native Images): Serverless, fast startup

Consider Alternatives For

  • Short-Lived Scripts: CLI tools, build scripts
  • Heavy C Extension Use: Applications relying on many native gems
  • Conservative Environments: Where stability is critical over performance
  • Simple Web Applications: Basic CRUD apps may not benefit
  • Development/Testing: Slower feedback loop due to warmup

Quick Navigation

Related Topics

Video Tutorial

Watch and learn truffleruby - high-performance ruby on graalvm

Pro Tip: After reading through the content above, watch this video to reinforce your understanding and see the concepts in action!