Stupid Golang Bugs

I’ve been converting a couple of Ruby scripts at work into Golang programs recently. There’s nothing especially wrong with the Ruby scripts except that they run a bit slower than I’d like. The scripts mostly do basic data analysis and statistics. It’s nothing incredibly intensive but there’s a lot of data to sift through and it’s largely coming from S3 buckets.

The scripts are run using the JRuby runtime which has great multithreading capabilities though the script probably doesn’t take full advantage of the concurrency primitives available to it. I’ve been looking for ways to write more Golang to get more comfortable with the language and was curious if a Golang rewrite would produce a faster solution.

In the midst of this work, I discovered something I hadn’t realized about working with slices. Here’s a code snippet:

var input []string // Assume this is prepopulated with 100 values.
someSlice := make([]string, 100)

for _, i := range input {
    someSlice = append(someSlice, i)
}

Can you spot the bug?

Due to using the make call, the slice is preallocated with 100 elements. However, when we populate someSlice, we’re using append instead of an assignment. In retrospect, this is obvious but I wasn’t thinking very hard when I wrote the original problematic code.

The result of the code above is a slice of length 200 where the first 100 elements are just empty strings.

Don’t be like me - either index and assign or use append.



Posted on 2021-02-02