Подтвердить что ты не робот

Как уменьшить размер скомпилированного файла?

Давайте сравним c и идем: Hello_world.c:

#include<stdio.h>
int main(){
    printf("Hello world!");
}

Hello_world.go:

package main
import "fmt"
func main(){
    fmt.Printf("Hello world!")
}

Скомпилируйте оба:

$gcc Hello_world.c -o Hello_c 
$8g Hello_world.go -o Hello_go.8
$8l Hello_go.8 -o Hello_go

и... что это такое?

$ls -ls
... 5,4K 2010-10-05 11:09 Hello_c
... 991K 2010-10-05 11:17 Hello_go

О 1Mb Привет, мир. Ты шутишь, что ли? Что я делаю неправильно?

(только строка Hello_go → 893K)

4b9b3361

Ответ 1

Проблема в том, что файл больше? Я не знаю Go, но я бы предположил, что он статически связывает некоторые библиотеки времени выполнения, что не относится к программе C. Но, вероятно, это не о чем беспокоиться, как только ваша программа станет больше.

Как описано здесь, статическая привязка времени выполнения Go является значением по умолчанию. На этой странице также описано, как настроить динамическую компоновку.

Ответ 2

Если вы используете систему на базе Unix (например, Linux или Mac OSX), вы можете попробовать удалить информацию об отладке, включенную в исполняемый файл, создав ее с помощью флага -s:

go build -ldflags "-s" prog.go

Я не знаю, как это сделать в Windows, но в Linux размеры файлов резко сокращаются.

Подробнее см. страницу GDB: http://golang.org/doc/gdb

Ответ 3

Ответ 2016 года:

1. Используйте Go 1.7

2. Скомпилировать с помощью go build -ldflags "-s -w"

➜ ls -lh hello
-rwxr-xr-x 1 oneofone oneofone 976K May 26 20:49 hello*

3. Затем используйте upx, goupx больше не требуется с 1.6.

➜ ls -lh hello
-rwxr-xr-x 1 oneofone oneofone 367K May 26 20:49 hello*

Ответ 4

Go двоичные файлы большие, потому что они статически связаны (за исключением привязок библиотек с использованием cgo). Попробуйте статически связать программу C, и вы увидите, что она растет до сопоставимого размера.

Если это действительно проблема для вас (которую я с трудом верю), вы можете скомпилировать ее с помощью gccgo и динамически связать.

Ответ 5

Вы должны получить goupx, он будет "исправлять" исполняемые файлы Golang ELF для работы с upx. В некоторых случаях у меня уже около 78% размера файла ~16MB >> ~3MB.

Коэффициент сжатия обычно составляет 25%, поэтому стоит попробовать:

$ go get github.com/pwaller/goupx
$ go build -o filename
$ goupx filename
<Р → >
2014/12/25 10:10:54 File fixed!

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
  16271132 ->   3647116   22.41%  linux/ElfAMD   filename                            

Packed 1 file.

EXTRA: флаг -s (полоса) может сжать файл bin еще больше goupx -s filename

Ответ 6

Более компактный пример hello-world:

package main

func main() {
  print("Hello world!")
}

Мы пропустили большой пакет fmt и заметно уменьшили двоичный файл:

  $ go build hello.go
  $ ls -lh hello
  ... 259K ... hello2
  $ strip hello
  $ ls -lh hello
  ... 162K ... hello2

Не такой компактный, как C, но хотя и измеряется в K не M:) Хорошо, это не общий способ, просто показывает некоторые способы оптимизации размера: используйте полосу и попытайтесь использовать минимальные пакеты. В любом случае Go не является языком для создания миниатюрных бинарных файлов.

Ответ 7

создайте файл с именем main.go, попробуйте с простой мировой программой приветствия.

package main

import "fmt"

func main(){
    fmt.Println("Hello World!")
}

Я использую go version 1.9.1

$ go version
 go version go1.9.1 linux/amd64

Скомпилируйте стандартную команду go build.

$ go build main.go
$ ls -lh
-rwxr-xr-x-x 1 nil nil 1.8M Oct 27 07:47 main

Скомпилируйте еще раз go build, но с ldflags, как было предложено выше,

$ go build -ldflags "-s -w" main.go
$ ls -lh
-rwxr-xr-x-x 1 nil nil 1.2M Oct 27 08:15 main

Размер файла уменьшается на 30%.

Теперь, используйте gccgo,

$ go version
 go version go1.8.1 gccgo (GCC) 7.2.0 linux/amd64

Построение с gccgo,

$ go build main.go
$ ls -lh
-rwxr-xr-x 1 nil nil 34K Oct 27 12:18 main

Двоичный размер уменьшается почти на 100%. Давайте еще раз попытаемся построить наш main.go с помощью gccgo, но с флагами сборки,

$ go build -gccgoflags "-s -w" main.go
-rwxr-xr-x 1 nil nil 23K Oct 27 13:02 main

Внимание: Так как бинарные файлы gccgo были динамически связаны. Если у вас есть бинарный файл, который очень большой по размеру, ваш двоичный файл при компиляции с gccgo не будет уменьшен на 100%, но он будет уменьшен в размере на значительное количество.

По сравнению с gc, gccgo медленнее компилирует код, но поддерживает более мощные оптимизации, поэтому программа с привязкой к процессору, созданная gccgo, будет работать быстрее. Доступны все оптимизации, реализованные в GCC на протяжении многих лет, включая встраивание, оптимизацию циклов, векторизация, планирование команд и многое другое. Хотя он не всегда дает лучший код, в некоторых случаях программы, скомпилированные с помощью gccgo, могут работать на 30% быстрее.

Ожидается, что выпуски GCC 7 будут включать полную реализацию пользовательских библиотек Go 1.8. Как и в предыдущих версиях, среда выполнения Go 1.8 не полностью слита, но это не должно быть видимым для программ Go.

Плюсы:

  • Уменьшенный размер
  • Оптимизированный.

против

  • Низкая
  • Невозможно использовать последнюю версию go.

Здесь вы можете увидеть здесь и здесь.

Ответ 8

Двоичный файл содержит по умолчанию сборщик мусора, систему планирования, управляющую процедурами go и все импортируемые библиотеки.

Результат - минимальный размер около 1 Мб.

Ответ 9

От Go 1.8 вы также можете использовать новую систему плагинов, чтобы разбить ваш двоичный код на нечто, похожее на общие библиотеки. Для этой версии он работает только в Linux, но в будущем, возможно, будут поддерживаться другие платформы.

https://tip.golang.org/pkg/plugin/