---
title: "Optimizing Ruby Lazy Initialization in TruffleRuby with Deoptimization"
description: "The post examines how TruffleRuby can optimize Ruby’s ||= operator when it is used for lazy initialization rather than repeated assignment. Static profiling of 20 popular open-source projects found 2,082 uses, with 64% meeting conservative criteria based on constant values or naming patterns for parameterless methods assigning instance or class variables. The implementation replaces the usual OrNode with an OrLazyValueDefinedNode, which counts executions of the right-hand side and deoptimizes when it is executed fewer than twice, allowing uncommon assignment paths to remain in the interpreter. In a benchmark, the change compiled code about 6% faster and produced about 63% less machine code by memory, although the post notes that benchmarking larger projects is noisy and the runtime impact is difficult to prove."
---

# Optimizing Ruby Lazy Initialization in TruffleRuby with Deoptimization

[Shopify](https://yomu.fyi/company/shopify) · 2023-10-18 · Mar 31, 2020

**Type:** Explainer

## Summary

The post examines how TruffleRuby can optimize Ruby’s ||= operator when it is used for lazy initialization rather than repeated assignment. Static profiling of 20 popular open-source projects found 2,082 uses, with 64% meeting conservative criteria based on constant values or naming patterns for parameterless methods assigning instance or class variables. The implementation replaces the usual OrNode with an OrLazyValueDefinedNode, which counts executions of the right-hand side and deoptimizes when it is executed fewer than twice, allowing uncommon assignment paths to remain in the interpreter. In a benchmark, the change compiled code about 6% faster and produced about 63% less machine code by memory, although the post notes that benchmarking larger projects is noisy and the runtime impact is difficult to prove.

## Context

Ruby’s ||= syntax assigns when a value is not set, but its common idiomatic use is “assign once.” Treating that usage as a special case could shorten the logic flow compiled by TruffleRuby and reduce emitted machine code.

## Approach / What changed

The implementation replaces the standard OrNode with an OrLazyValueDefinedNode in the BodyTranslator. The new node counts executions of the right-hand side and deoptimizes when that path is executed fewer than twice, leaving the uncommon assignment path in the interpreter instead of compiling it into the fast machine-code path.

## Takeaways

- TruffleRuby represents Ruby program parts with nodes, and the ||= implementation is written in Java; the specialized node is selected during Ruby AST translation.
- The optimization is intended to disappear when ||= is not being used for lazy initialization, when its right-hand side must run multiple times, or when that path needs to be fast.
- The measured change compiled a sample about 6% faster and reduced machine-code memory by about 63%, with roughly half as many assembly instructions; broader runtime gains were difficult to prove.

**Tags:** [Performance](https://yomu.fyi/topic/performance), [Ruby](https://yomu.fyi/topic/ruby), [TruffleRuby](https://yomu.fyi/topic/truffleruby)

- Source: [Shopify](https://shopify.engineering/optimizing-ruby-lazy-initialization-in-truffleruby-with-deoptimization)
- Source URL: https://shopify.engineering/optimizing-ruby-lazy-initialization-in-truffleruby-with-deoptimization
- Ingested by Yomu: 2026-08-31T01:13:01.905Z

[Read original post](https://shopify.engineering/optimizing-ruby-lazy-initialization-in-truffleruby-with-deoptimization)
