Why is Golang's Compilation Speed So Fast?

  tr_cn        2024-10-07 22:02:23       3,414        1    

Overview

When I started learning the Go language, I already had experience with three statically typed languages—C/C++ and Java—and two dynamically typed languages—PHP and JavaScript. Because of this background, when I compiled a demo file of several hundred lines for the first time in Go, I was genuinely impressed by its compilation speed. At that moment, I thought to myself, "Go claims to have the execution speed of statically typed languages and the compilation speed of dynamically typed languages—it indeed lives up to its reputation." Indeed, one of the primary motivations behind Google inventing Go was to solve the problem of lengthy build times for large-scale projects internally. Leaving aside the historical context of the technology's development, this article focuses on the main optimization strategies behind Go's compilation speed.

Minimal Keywords

Go has only 25 keywords, which helps shorten compilation time.

Symbol Table

A symbol table is a data structure in the compiler used to store identifiers in the program (such as variables, functions, structs/objects), mainly serving to provide a way to manage these identifiers efficiently for referencing, resolving, optimizing, etc., during different stages of compilation.

In Go, there isn't a direct (explicit) symbol table; instead, the compiler creates some internal data structures to manage identifiers and type information during compilation. Although these internal data structures aren't directly exposed to developers as a symbol table, they can be considered the compiler's "internal symbol table." Additionally, Go provides reflection mechanisms that allow retrieving types, struct fields, calling methods/stacks, etc., at runtime, as well as accessing and modifying object fields. Developers can obtain similar information to a symbol table through this indirect means.

Dependency Analysis

This is the main reason for the performance boost in Go's compilation speed.

Eliminating Circular Dependencies

When circular dependencies appear in Go, the compiler will report an error. Once developers resolve the circular dependencies, the compilation process needs only to recurse to the bottom of the dependency tree, essentially a Depth-First Search (DFS) process. Furthermore, under the condition of no circular dependencies, each package can be compiled independently and in parallel.

Simplifying Dependencies

In Go code files, you only need to include the names of packages that are directly used in the code. For example, when needing to use the Cookie object, you only need to import the cookiejar package and not the http package.

package main

import "net/http/cookiejar"

func main() {
	var c cookiejar.Jar
}

At the same time, importing unused packages in Go will result in a compilation error:

imported and not used:  ...

This pre-compilation constraint ensures that unrelated packages do not affect compilation time.

Lastly, Go requires that all packages used in the source file must be listed at the beginning of the file (after the `package` statement). Thus, the compiler does not need to read the entire file to determine dependencies. The target files of already compiled Go packages record not only the exported information of the package but also the exported information of the packages it depends on. When compiling, you only need to import a target file without checking other information.

No Support for Overloading/Rewriting

Go does not support method rewriting or method overloading, meaning all methods can be considered statically typed, similar to static methods in Java.

class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!"); 
    }
}

No Support for Templates

Go also does not support template methods, which avoids the performance overhead brought by template instantiation.

No Need for a Virtual Machine

Like Java, Go is a language with built-in Garbage Collection (GC), but unlike Java, which compiles within a virtual machine, Java code must be compiled into bytecode before passing through the compiler. However, Go does not depend on a virtual machine to compile code but rather compiles directly from source code to binary files.

Translated from https://dbwu.tech/posts/golang/why_golang_compiles_so_fast/

GO  GOLANG  COMPILATION 

       

  RELATED


  1 COMMENT


Anonymous [Reply]@ 2024-11-26 03:36:48

You forgot one of the most important when developing locally: package-level caching!



  RANDOM FUN

Bug 404