Давайте сравним 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
Около 1Мб Привет, мир. Ты шутишь, что ли? Что я делаю не так?
(убрать Hello_go -> 893K только)
Ответы:
Проблема в том, что файл больше? Я не знаю Go, но я предполагаю, что он статически связывает некоторую библиотеку времени выполнения, что не относится к программе C. Но, вероятно, не о чем беспокоиться, как только ваша программа станет больше.
Как описано здесь , по умолчанию используется статическая привязка среды выполнения Go. На этой странице также рассказывается, как настроить динамическое связывание.
источник
Если вы используете систему на основе Unix (например, Linux или Mac OSX), вы можете попробовать удалить отладочную информацию, включенную в исполняемый файл, создав ее с флагом -w:
go build -ldflags "-w" prog.go
Значительно уменьшаются размеры файлов.
Для получения дополнительной информации посетите страницу GDB: http://golang.org/doc/gdb
источник
strip
команды:go build prog.go; strip prog
тогда мы получили так называемый чередующийся исполняемый файл: ELF 64-битный LSB исполняемый файл, x86-64, версия 1 (SYSV), динамически скомпонованный (использует общие библиотеки), разделенный-w
вместо-s
. Не уверен, в чем разница, но, возможно, вы захотите обновить свой ответ :-)Ответ 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*
источник
Бинарные файлы Go имеют большой размер, потому что они статически связаны (за исключением связывания библиотек с помощью cgo). Попробуйте статически связать программу C, и вы увидите, что она вырастет до сопоставимого размера.
Если это действительно проблема для вас (в что мне трудно поверить), вы можете скомпилировать с помощью gccgo и динамически связать.
источник
Вы должны получить 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.
ДОПОЛНИТЕЛЬНО:
-s
флаг (полоса) может еще больше уменьшить размер файла bingoupx -s filename
источник
создайте файл с именем
main.go
, давайте попробуем с помощью простой программы hello world.package main import "fmt" func main(){ fmt.Println("Hello World!") }
Пользуюсь go версии 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
.Вы можете увидеть здесь и здесь .
источник
gogcc
не поддерживает процессор ARM, верно? И, можете ли вы предложить инструмент, который уменьшает размер файла сборки Golang?Более компактный пример 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 - это не язык для создания двоичных файлов маленького размера.
источник
Вы можете взглянуть на мое небольшое исследование по этой теме: https://github.com/xaionaro/documentation/blob/master/golang/reduce-binary-size.md
В нем пошагово показано, как уменьшить статический двоичный образец hello-world размером 2 МБ до статического двоичного значения 15 КБ или динамического двоичного кода 10 КБ. Конечно, есть много ограничений.
источник
2018 ответ на следующий Go 1.11, в твиттере по Брэд Фитцпатрик ( в середине июня 2018 года):
Ср. Проблема с Golang 11799 :
См. Больше в коммите 594eae5
Роб Пайк упоминает :
Брэд ответил:
Причины : информация об отладке, но также зарегистрируйте карту для GC, чтобы любая инструкция могла быть точкой сохранения.
источник
По умолчанию gcc подключается динамически, а работает - статически.
Но если вы свяжете свой код C статически, вы можете получить двоичный файл большего размера.
В моем случае:
оба двоичных файла статически связаны и не имеют debug_info.
go build -ldflags="-s -w" -o test-go test.go gcc -static -s -o test-c test.c
источник
Бинарный файл по умолчанию содержит сборщик мусора, систему планирования, которая управляет подпрограммами go, и все библиотеки, которые вы импортируете.
В результате получается минимальный размер около 1 Мб.
источник
Начиная с Go 1.8 вы также можете использовать новую систему плагинов, чтобы разделить двоичный файл на что-то, напоминающее общие библиотеки. В этом выпуске он работает только в Linux, но, вероятно, в будущем будут поддерживаться и другие платформы.
https://tip.golang.org/pkg/plugin/
источник