Skip to content

Proposal: Add throw/catch backend option for Do notation (faster failure paths) #199

@taman9333

Description

@taman9333

Description

While exploring the Do notation implementation, I discovered that Ruby's throw/catch mechanism could provide a faster alternative to the current exception-based approach, particularly for failure-heavy workloads. I wanted to share my findings and discuss whether this would be a valuable addition to the library.

Context

The current Do notation uses exceptions (Halt) for control flow, which has the benefit of working seamlessly with database transactions (automatic rollback). However, I was curious whether alternative control flow mechanisms could offer better performance.

Benchmarks (Ruby 3.4.5)

I benchmarked three approaches:

  • raise/rescue (current implementation)
  • throw/catch (Ruby's non-local return)
  • Fiber.yield/resume
Scenario raise throw fiber
3-step success 554k i/s 522k i/s 321k i/s
Early failure (step 1) 571k i/s 757k i/s 366k i/s
Middle failure (step 2) 409k i/s 529k i/s 291k i/s
Late failure (step 3) 343k i/s 419k i/s 245k i/s
Realistic operation failure 405k i/s 511k i/s 277k i/s

Proposal

I'm not suggesting replacing the current raise backend, it's valuable because it works with transaction blocks automatically. Instead, I'd like to propose adding an optional backend to use throw instead of raise and when using the throw backend, users would handle transactions explicitly in a base class.

So I would like to know if that's something you'd consider adding to the library? If there's interest, I'd be happy to submit a PR with the implementation

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions