vgobenchmarks
V versus Go, measured on the same machine
Compile times, binary size and runtime for V 0.5.2 and Go 1.27.1 on identical work, plus the language differences that show up in the first hour of porting.
V is usually described as faster to compile than Go. I wanted to check that
rather than repeat it, so I ran the same program through both: sum a slice of
200,000 ints, 100 times.
package main
func sumAll(numbers []int) int {
total := 0
for _, n := range numbers {
total += n
}
return total
}
func main() {
numbers := make([]int, 200_000)
for i := range numbers {
numbers[i] = i
}
acc := 0
for i := 0; i < 100; i++ {
acc += sumAll(numbers)
}
println("go:", acc)
}
V 0.5.2 (7647ce1) and Go 1.27.1, Windows, same machine, best of three after a
warm-up run.V 0.5.2Go 1.27.1Compile, cache empty0.32s2.15sCompile, warm cache0.32s0.10sRun36ms16msBinary327 kB1813 kBGo is faster to recompile, not slowerThis is the part that does not match the usual framing. V's headline is fast
compilation, and it is — but compilation here is not compile-from-scratch. V
compiles straight to C and hands it to a C compiler, so "cold" for V still means
the C toolchain's objects are cached.Go wins the loop that matters day to day. Once GOCACHE is warm, an incremental
build is about 100ms, against V's 320ms which does not improve. If you are
tightening a loop with a save-rebuild-run cycle, Go is the faster one there, and
by three times.Cold builds are where V wins, 0.32s against 2.15s, and the gap widens if the
cache is fully cleared — go clean -cache then build took 9.16s the first time
in this test and 2.15s once the standard library's own objects were cached again.V's binary is a fifth of Go's327 kB against 1813 kB. Go's binaries are famously large because they carry the
runtime and type metadata for garbage collection. V compiles to C, so the output
is whatever the C compiler produces, and the runtime is closer to C's.Runtime is a wash either wayV took 36ms, Go 16ms. Both are dominated by the same loop doing the same integer
adds. A 2x difference on integer arithmetic is not a reason to pick a language;
the allocator and the garbage collector decide that, not the syntax. I would not
build an argument on this number in either direction.What else movedGoVMutabilityEverything mutablemut required, compiler enforcedFormattergofmt -l is idempotentv fmt -verify fails on its own outputString helpersstrings.Split(s, ",")"s".split(",")strings module~20 functions5 functionsExitos.Exit(0)exit(0), builtinModule filego.modv.modThe mutability default is the part I like most about V, and it is the part that
costs a Go programmer nothing. Everything in Go is mutable unless you go looking
for a type that is not, which means every line you read has to be checked for
aliasing. In V, mut is written at the point where mutation is intended, so
reading the declaration tells you whether a variable changes.Where I would stopIf I already knew Go, I would stay on Go for anything with a dependency
ecosystem I care about. V's advantage is compile speed on a cold cache, smaller
binaries, and enforced mutability. None of those are reasons to rewrite working
code.V is worth learning for the language design, and worth using where the compile
and binary-size numbers matter — a CLI that ships as one file, or a build that
starts from scratch on every CI run.