proc f {} {
yield [set a 0]
yield [set b 1]
while 1 {
yield [incr a $b]
lassign [list $b $a] a b
}
}
coroutine fib fThe call to coroutine is considered to be fib(0) and returns 0. Add a nullary yield (or the customary yield [info coroutine]) before the first yield to make the first call to fib the zeroth call.It's about six times slower than ::math::fibonacci, but it's hard to compare timing when the coroutine needs to be destroyed and reinstated during every iteration, and the call to fib wrapped in a for statement to advance the sequence.Time by:time {for {set i 0} {$i <= 46} {incr i} fib ; rename fib "" ; coroutine fib f} 100000 ;# relative 5.5
time {::math::fibonacci 46} 100000 ;# relative 1.0This command allows the Fibonacci series to be restarted if an argument is passed to fib:
proc f {} {
yield
while 1 {
yield [set a 0]
yield [set b 1]
while {[yield [incr a $b]] eq {}} {
lassign [list $b $a] a b
}
}
}
coroutine fib fIt is only slightly faster than the first command. Using this code and calling fib 46 times instead of using a loop makes this implementation about three times slower than ::math::fibonacci.Time by:time {for {set i 0} {$i <= 46} {incr i} fib ; fib stop} 100000 ;# relative 4.9
time {
fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib
fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib
fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib
fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib ; fib
fib ; fib ; fib ; fib ; fib ; fib
fib reset
} 100000 ;# relative 3.1
