FYI, map
is a reserved word, so you can't make your function exactly as written with lowercase map
.
That is probably as good as you can get. Generics don't get you around allocating new memory.
It is slightly faster to use append() rather than initializing the whole slice to empty strings at the beginning. For example:
func Map(list []string, op func(string) string) []string {
output := make([]string, 0, len(list))
for _, v := range list {
output = append(output, op(v))
}
return output
}
This gave me about a 10% increase in speed.
Update: That was only true for very short slices. Here's a more thorough benchmark--it was actually slower to use append on longer slices. I also tried parallelizing it, which was only worth the overhead on much bigger slices.
Code:
https://gist.github.com/8250514
Output (numbers at end of test names are slice lengths):
go test -bench=".*" -test.cpu=2
BenchmarkSliceMake10-2 5000000 473 ns/op
BenchmarkSliceMake100-2 500000 3637 ns/op
BenchmarkSliceMake1000-2 50000 43920 ns/op
BenchmarkSliceMake10000-2 5000 539743 ns/op
BenchmarkSliceAppend10-2 5000000 464 ns/op
BenchmarkSliceAppend100-2 500000 4303 ns/op
BenchmarkSliceAppend1000-2 50000 51172 ns/op
BenchmarkSliceAppend10000-2 5000 595650 ns/op
BenchmarkSlicePar10-2 500000 3784 ns/op
BenchmarkSlicePar100-2 200000 7940 ns/op
BenchmarkSlicePar1000-2 50000 50118 ns/op
BenchmarkSlicePar10000-2 5000 465540 ns/op