Skip to content

Latest commit

 

History

History
116 lines (85 loc) · 4.25 KB

File metadata and controls

116 lines (85 loc) · 4.25 KB

Performance Analysis: Ruby2html vs Phlex

Benchmark Results

Slim:                367.2 i/s (fastest)
ERB:                 298.8 i/s
Phlex:               279.4 i/s (pure Ruby!)
Ruby2html templates: 118.4 i/s (2.36x slower than Phlex)
Ruby2html components:119.4 i/s

Why is Phlex Faster Despite Being Pure Ruby?

Key Architectural Differences

  1. Direct Instantiation vs Template Handling

    • Phlex: render PhlexView.new(data) - direct class instantiation
    • Ruby2html: Rails template handler → instance_exec → context setup
    • Impact: Template handling adds overhead
  2. No Instance Variable Copying

    • Phlex: Data passed as constructor argument
    • Ruby2html: Copies all instance variables from controller context
    • Impact: Even with our optimizations, copying still has cost
  3. Buffer Management

    • Phlex: Highly optimized string buffer with minimal allocations
    • Ruby2html: Creates new Render instance per request, pre-allocates buffers
    • Impact: Phlex's buffer reuse is more efficient
  4. Method Call Overhead

    • Phlex: Optimized internal method dispatch
    • Ruby2html: Block calls for every tag, method_missing delegation
    • Impact: Higher method call overhead
  5. String Interpolation

    • Ruby2html template: Uses plain method for every interpolated string
    • Phlex: Direct string handling in blocks
    • Impact: Extra method calls in Ruby2html

Optimization Opportunities Implemented

We implemented 7 major C-level optimizations:

  1. C Tag Generation - 2-3x faster tag operations
  2. SIMD HTML Escaping (SSE4.2) - 3-10x faster for clean strings
  3. Cached Instance Variables - Reduced per-render overhead
  4. Direct Hash Iteration - Eliminated array allocations
  5. Lookup Table Escaping - Branch-free character lookups
  6. Type Optimization - size_t, unsigned types
  7. Compiler Hints - const, restrict, inline, loop unrolling

Result: 2-4x faster than original, but still 2.36x slower than Phlex

Why Our C Optimizations Didn't Beat Pure Ruby Phlex

The Fundamental Issue: Architecture vs Micro-optimizations

We optimized the wrong layer:

  • ✅ Optimized: Tag generation, escaping, attributes (micro-level)
  • ❌ Not optimized: Template handling, instance variables, method dispatch (macro-level)

Analogy: We made the engine faster, but Phlex has a lighter car.

What Phlex Does Right

  1. Minimal Abstraction: Direct Ruby code, no template parsing
  2. Zero Context Overhead: No instance variable copying
  3. Optimized for Common Case: Fast path for trusted content
  4. Smart Buffer Management: Reuses buffers efficiently

What Limits Ruby2html

  1. Rails Template Integration: Can't avoid template handler overhead
  2. View Context Coupling: Must work with controller instance variables
  3. Escaping by Default: Conservative (secure) but slower
  4. Block-Based DSL: More flexible but higher overhead

Recommendations

For Ruby2html Users

When to use Ruby2html:

  • Need .html.rb template files (Rails conventions)
  • Want automatic HTML escaping (security-first)
  • Prefer template-based architecture

When to use Phlex:

  • Maximum performance is critical
  • Component-based architecture preferred
  • Can manage content escaping manually

Future Optimization Opportunities

  1. Bypass Template Handler - Direct component rendering like Phlex
  2. Eliminate Instance Variable Copying - Pass data explicitly
  3. Optimize plain Method - Inline or eliminate extra calls
  4. Buffer Pooling - Reuse buffers across requests
  5. JIT Compilation - Cache compiled templates

Conclusion

Our C optimizations are excellent for the code they optimize, achieving:

  • 2-4x improvement over original Ruby2html
  • Branch-free operations
  • SIMD acceleration
  • Minimal allocations

However, Phlex is faster because of superior architecture, not better optimizations:

  • No template overhead
  • No context copying
  • Minimal method calls
  • Optimized for the common case

Key Lesson: Architecture matters more than micro-optimizations. A well-designed pure Ruby solution (Phlex) can beat a heavily optimized solution with architectural overhead (Ruby2html + C extensions).