Mahdi
All posts
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.

Related