Skip to content

cmd/compile: simple integer computation loop is relatively slow #59366

@keakon

Description

@keakon

What version of Go are you using (go version)?

$ go version
go version go1.20.2 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/keakon/Library/Caches/go-build"
GOENV="/Users/keakon/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/keakon/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/keakon/go"
GOPRIVATE=""
GOPROXY="https://goproxy.cn,direct"
GOROOT="/usr/local/Cellar/go/1.20.2/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.20.2/libexec/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.20.2"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="cc"
CXX="c++"
CGO_ENABLED="1"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/jw/d0g3224x6tx5dwqrvkl8pp440000gn/T/go-build1704497747=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Build and run them:

$ go run main.go

package main

import (
	"fmt"
	"time"
)

func main() {
	start := time.Now()
	r := uint64(0)
	for i := uint64(0); i < 10000000000; i++ {
		m := i * i
		if r > m {
			r -= m
		} else {
			r += m
		}
	}
	end := time.Now()
	fmt.Println(end.Sub(start), r)
}

$ clang -O3 main.c -o main && ./main

#include <stdio.h>
#include <time.h>

int main() {
	struct timespec start, end;
	unsigned long long r = 0;
	clock_gettime(CLOCK_MONOTONIC, &start);
	for (unsigned long long i = 0; i < 10000000000; i++) {
		unsigned long long m = i * i;
		if (r > m) {
			r -= m;
		} else {
			r += m;
		}
	}
	clock_gettime(CLOCK_MONOTONIC, &end);
	unsigned long long elapsed_time = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000;
	printf("%llu %llu\n", elapsed_time, r);
	return 0;
}

$ zig build-exe -O ReleaseFast main.zig && ./main

const std = @import("std");

pub fn main() void {
    const start = std.time.milliTimestamp();
    var i: u64 = 0;
    var r: u64 = 0;
    while (i < 10000000000) : (i += 1) {
        var m = i * i;
        if (r > m) {
            r -= m;
        } else {
            r += m;
        }
    }
    const end = std.time.milliTimestamp();
    std.debug.print("{d} {d}\n", .{ end - start, r });
}

What did you expect to see?

Go should run as fast as C and Zig.

What did you see instead?

Go spent over 9 seconds, C (clang 14) and Zig (0.10.1) spent about 4 seconds.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Performancecompiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions