Node.js's BigInteger.+ beats attaswift.BigInt.+ by about 3x for the specific case that's being exercised here (n = 10,000), which is precisely within expectations for a naive implementation.

## Swift code

```
import BigInt
func fibonacci(_ n: Int) -> BigInt {
precondition(n > 0)
if n == 1 {
return 0
}
var previous: BigInt = 0
var current: BigInt = 1
for _ in 2 ... n {
let next = previous + current
previous = current
current = next
}
return current
}
let counts = [10000, 30000, 100000, 300000, 1000000]
for c in counts {
print(c)
var f: BigInt = 0
let clock = ContinuousClock()
var duration = clock.measure {
f = fibonacci(c)
}
print("fibonacci: \(duration)")
duration = clock.measure {
print(f)
}
print("print: \(duration)")
}
```

## Node.js code

```
function fib_loop(n) {
if (n <= 1) {
return BigInt(n);
} else {
let a = BigInt(0);
let b = BigInt(1);
let temp;
for (let i = 2; i <= n; i++) {
temp = a + b;
a = b;
b = temp;
}
return b.toString();
}
}
let counts = [10000, 30000, 100000, 300000, 1000000];
for (let i = 0; i < counts.length; i++) {
let c = counts[i];
console.log(c);
console.time("fib_loop");
let f = fib_loop(c);
console.timeEnd("fib_loop");
console.time("print");
console.log(f);
console.timeEnd("print");
}
```

## Interesting, but ultimately irrelevant benchmark data

Interestingly, the gap widens to ~6x on larger values:

Count | node.js | Swift | ratio |
---|---|---|---|

10,000 | 1.558ms | 4.345ms | 2.78x |

30,000 | 8.794ms | 33.127ms | 3.76x |

100,000 | 69.763ms | 350.025ms | 5.02x |

300,000 | 552.623ms | 3056.003ms | 5.52x |

1,000,000 | 5.944s | 34.368s | 5.78x |

(Switching to using `BigUInt`

and `+=`

is expected to eliminate the allocation overhead. Doing that shaves off a few percentages, but it doesn't meaningfully close the gap.)

Radix conversions are particularly slow in my old library. For n = 10,000, attaswift does its decimal conversion about 7x slower than Node.js. Other values demonstrate that the latter may have an algorithmic advantage:

Count | node.js | Swift | ratio |
---|---|---|---|

10,000 | 0.024ms | 0.164ms | 6.8x |

30,000 | 0.047ms | 1.199ms | 25.5x |

100,000 | 0.076ms | 12.006ms | 158x |

300,000 | 0.18ms | 109.942ms | 611x |

1,000,000 | 0.536ms | 1273.589ms | 2376x |

It would be useful to follow up on these to rule out Standard Library issues. However, these are most likely due to a multitude of package-level issues. (I wrote this stuff almost a decade ago, in the Swift 2 era. Swift 4 was in beta the last time I was able to update this code.)