История изменений
Исправление korvin_, (текущая версия) :
Выше я имел в виду расходы на канал.
Однако горутины да, дадут некоторое проседание при большом числе вызовов.
package main
import (
	"fmt"
	"time"
)
const N = 10000000
func tco1(res chan int, x int) {
	if x > N {
		res <- x
		return
	}
	go tco2(res, x+1)
}
func tco2(res chan int, x int) {
	go tco1(res, x+2)
}
func tco(x int) int {
	res := make(chan int)
	go tco1(res, x)
	return <-res
}
type stateF func(int) (int, stateF)
func state(x int) int {
	x, f := state1(x)
	for {
		if f == nil {
			break
		}
		x, f = f(x)
	}
	return x
}
func state1(x int) (int, stateF) {
	if x > N {
		return x, nil
	}
	return x+1, state2
}
func state2(x int) (int, stateF) {
	return x+2, state1
}
func test(title string, f func(int) int) {
	fmt.Printf("%s: ", title)
	start := time.Now()
	res   := f(1)
	fmt.Printf("%d, %v\n", res, time.Since(start))
}
func main() {
	test("goroutine", tco)
	test("stateloop", state)
}
% go run tco.go
goroutine: 10000003, 2.220127s
stateloop: 10000003, 52.003ms
Исправление korvin_, :
Однако горутины да, дадут некоторое проседание при большом числе вызовов.
package main
import (
	"fmt"
	"time"
)
const N = 10000000
func tco1(res chan int, x int) {
	if x > N {
		res <- x
		return
	}
	go tco2(res, x+1)
}
func tco2(res chan int, x int) {
	go tco1(res, x+2)
}
func tco(x int) int {
	res := make(chan int)
	go tco1(res, x)
	return <-res
}
type stateF func(int) (int, stateF)
func state(x int) int {
	x, f := state1(x)
	for {
		if f == nil {
			break
		}
		x, f = f(x)
	}
	return x
}
func state1(x int) (int, stateF) {
	if x > N {
		return x, nil
	}
	return x+1, state2
}
func state2(x int) (int, stateF) {
	return x+2, state1
}
func test(title string, f func(int) int) {
	fmt.Printf("%s: ", title)
	start := time.Now()
	res   := f(1)
	fmt.Printf("%d, %v\n", res, time.Since(start))
}
func main() {
	test("goroutine", tco)
	test("stateloop", state)
}
% go run tco.go
goroutine: 10000003, 2.220127s
stateloop: 10000003, 52.003ms
Исходная версия korvin_, :
Однако горутины да, дадут некоторое проседание при большом числе вызовов.
package main
import (
	"fmt"
	"time"
)
const N = 10000000
func tco1(res chan int, x int) {
	if x > N {
		res <- x
		return
	}
	go tco2(res, x+1)
}
func tco(x int) int {
	res := make(chan int)
	go tco1(res, x)
	return <-res
}
func tco2(res chan int, x int) {
	go tco1(res, x+2)
}
type stateF func(int) (int, stateF)
func state(x int) int {
	x, f := state1(x)
	for {
		if f == nil {
			break
		}
		x, f = f(x)
	}
	return x
}
func state1(x int) (int, stateF) {
	if x > N {
		return x, nil
	}
	return x+1, state2
}
func state2(x int) (int, stateF) {
	return x+2, state1
}
func test(title string, f func(int) int) {
	fmt.Printf("%s: ", title)
	start := time.Now()
	res   := f(1)
	fmt.Printf("%d, %v\n", res, time.Since(start))
}
func main() {
	test("goroutine", tco)
	test("stateloop", state)
}
% go run tco.go
goroutine: 10000003, 2.220127s
stateloop: 10000003, 52.003ms