Skip to content

Replace naive recursive Fibonacci with tail-recursive implementation for better performance - #28

Merged
jjc256 merged 1 commit into
mainfrom
copilot/fix-62f3da4b-522d-4592-9607-584a07669ded
Sep 2, 2025
Merged

Replace naive recursive Fibonacci with tail-recursive implementation for better performance#28
jjc256 merged 1 commit into
mainfrom
copilot/fix-62f3da4b-522d-4592-9607-584a07669ded

Conversation

Copilot AI commented Sep 2, 2025

Copy link
Copy Markdown
Contributor

This PR replaces the naive recursive Fibonacci function in bench/programs/fib_rec.tiny with a tail-recursive implementation using an accumulator pattern, addressing performance and stack overflow concerns.

Changes Made

Before (naive recursive):

let rec fib n =
  if n <= 1 then n
  else (fib (n - 1)) + (fib (n - 2))
in
fib 15

After (tail-recursive with accumulators):

let rec fib_iter n a b count =
  if n <= count then a
  else fib_iter n b (a + b) (count + 1)
in
let fib n = 
  if n <= 0 then 0
  else if n <= 1 then 1
  else fib_iter n 0 1 0
in
fib 500

Key Improvements

  1. Performance: Changed from exponential O(2^n) time complexity to linear O(n)
  2. Stack Safety: Tail-recursive implementation avoids stack overflow for large inputs
  3. Benchmark Visibility: Increased input from 15 to 500 for more meaningful benchmark timing
  4. Mathematical Correctness: Uses accumulator pattern with two consecutive Fibonacci numbers

Technical Details

The tail-recursive approach:

  • Uses helper function fib_iter(n, a, b, count) where a and b track consecutive Fibonacci numbers
  • Counts up from 0 to n instead of making two recursive calls per iteration
  • Each step: fib_iter(n, b, a+b, count+1)
  • Ensures the recursive call is the last operation, enabling tail call optimization

Testing

  • Added comprehensive test cases covering edge cases (fib(0), fib(1)) and larger values
  • All existing tests continue to pass (22/22)
  • Verified correctness in JavaScript interpreter (e.g., fib(10) = 55)
  • Updated .gitignore to exclude build artifacts

Screenshot

The implementation works correctly in the JavaScript interpreter as demonstrated:

Tail-recursive Fibonacci Implementation

The screenshot shows the tail-recursive implementation running successfully in the web UI, computing fib(10) = 55 correctly.

This pull request was created as a result of the following prompt from Copilot chat.

Replace the naive recursive Fibonacci function in fib_rec.tiny with a tail-recursive version, and set the input argument large enough (e.g., 200_000) so that the Wasm benchmark takes visible, nonzero time. The new code should use an accumulator-based helper for tail recursion and call fib with a large value to stress performance without stack overflow.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@vercel

vercel Bot commented Sep 2, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
tinyocaml2wasm Ready Ready Preview Comment Sep 2, 2025 5:08pm

@jjc256
jjc256 marked this pull request as ready for review September 2, 2025 17:08
@jjc256
jjc256 merged commit 2e06f64 into main Sep 2, 2025
3 checks passed
@jjc256
jjc256 deleted the copilot/fix-62f3da4b-522d-4592-9607-584a07669ded branch September 2, 2025 17:08
Copilot AI changed the title [WIP] Update fib_rec.tiny to use tail recursion and a large argument for benchmarking Replace naive recursive Fibonacci with tail-recursive implementation for better performance Sep 2, 2025
Copilot AI requested a review from jjc256 September 2, 2025 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants