Porównajmy c i przejdźmy: Hello_world.c:
#include<stdio.h>
int main(){
printf("Hello world!");
}
Hello_world.go:
package main
import "fmt"
func main(){
fmt.Printf("Hello world!")
}
Skompiluj oba:
$gcc Hello_world.c -o Hello_c
$8g Hello_world.go -o Hello_go.8
$8l Hello_go.8 -o Hello_go
i co to jest?
$ls -ls
... 5,4K 2010-10-05 11:09 Hello_c
... 991K 2010-10-05 11:17 Hello_go
Około 1Mb Witaj, świecie. Czy ty żartujesz? Co robię źle?
(usuń Hello_go - tylko> 893K)
Odpowiedzi:
Czy to problem, że plik jest większy? Nie wiem, czy Go, ale zakładam, że statycznie łączy pewną bibliotekę wykonawczą, co nie ma miejsca w przypadku programu C. Ale prawdopodobnie nie ma się czym martwić, gdy tylko twój program się powiększy.
Jak opisano tutaj , statyczne łączenie środowiska wykonawczego Go jest ustawieniem domyślnym. Ta strona zawiera również informacje o tym, jak skonfigurować dynamiczne łączenie.
źródło
Jeśli używasz systemu opartego na Uniksie (np. Linux lub Mac OSX), możesz spróbować usunąć informacje debugowania zawarte w pliku wykonywalnym, budując go z flagą -w:
go build -ldflags "-w" prog.go
Znacznie zmniejszają się rozmiary plików.
Aby uzyskać więcej informacji, odwiedź stronę GDB: http://golang.org/doc/gdb
źródło
strip
polecenia:go build prog.go; strip prog
wtedy otrzymaliśmy tak zwany plik wykonywalny w paski : plik wykonywalny ELF 64-bit LSB, x86-64, wersja 1 (SYSV), połączony dynamicznie (używa bibliotek współdzielonych), rozebrany-w
zamiast-s
. Nie jestem pewien, jaka jest różnica, ale możesz zaktualizować swoją odpowiedź :-)Odpowiedź z 2016 roku:
1. Użyj Go 1.7
2. Skompiluj z
go build -ldflags "-s -w"
➜ ls -lh hello -rwxr-xr-x 1 oneofone oneofone 976K May 26 20:49 hello*
3. Wtedy użycie
upx
,goupx
nie jest już potrzebne od 1.6.➜ ls -lh hello -rwxr-xr-x 1 oneofone oneofone 367K May 26 20:49 hello*
źródło
Pliki binarne Go są duże, ponieważ są połączone statycznie (z wyjątkiem powiązań bibliotek używających Cgo). Spróbuj łączyć statycznie program w C, a zobaczysz, że osiągnie on porównywalny rozmiar.
Jeśli jest to dla Ciebie naprawdę problem (w co trudno mi uwierzyć), możesz skompilować za pomocą gccgo i dynamicznie linkować.
źródło
Powinieneś dostać goupx , to "naprawi" pliki wykonywalne Golang ELF do pracy
upx
. W niektórych przypadkach już zmniejszyłem rozmiar pliku o około 78%~16MB >> ~3MB
.Współczynnik kompresji zwykle wynosi 25%, więc warto spróbować:
$ 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
flaga (strip) może jeszcze bardziej zmniejszyć plik bingoupx -s filename
źródło
utwórz plik o nazwie
main.go
, spróbujmy z prostym programem hello world.package main import "fmt" func main(){ fmt.Println("Hello World!") }
Używam go w wersji 1.9.1
$ go version go version go1.9.1 linux/amd64
Skompiluj za pomocą standardowego
go build
polecenia.$ go build main.go $ ls -lh -rwxr-xr-x-x 1 nil nil 1.8M Oct 27 07:47 main
Skompilujmy ponownie z,
go build
ale zldflags
jak zasugerowano powyżej,$ go build -ldflags "-s -w" main.go $ ls -lh -rwxr-xr-x-x 1 nil nil 1.2M Oct 27 08:15 main
Rozmiar pliku zostaje zmniejszony o 30%.
Teraz użyjmy
gccgo
,$ go version go version go1.8.1 gccgo (GCC) 7.2.0 linux/amd64
Budowanie iść z
gccgo
,$ go build main.go $ ls -lh -rwxr-xr-x 1 nil nil 34K Oct 27 12:18 main
Rozmiar binarny został zmniejszony o prawie 100%. Chodźmy znów próbować budować nasz
main.go
zgccgo
ale z wbudowanym flagami,$ go build -gccgoflags "-s -w" main.go -rwxr-xr-x 1 nil nil 23K Oct 27 13:02 main
Ostrzeżenie: As
gccgo
pliki binarne zostały połączone dynamicznie. Jeśli masz plik binarny, który jest bardzo duży, twój plik binarny po kompilacji za pomocą gccgo nie zostanie zmniejszony o 100%, ale zostanie znacznie zmniejszony.W porównaniu z gc, gccgo wolniej kompiluje kod, ale obsługuje bardziej zaawansowane optymalizacje, więc program związany z procesorem zbudowany przez gccgo będzie zwykle działał szybciej. Dostępne są wszystkie optymalizacje wdrożone w GCC na przestrzeni lat, w tym wstawianie, optymalizacje pętli, wektoryzacja, planowanie instrukcji i inne. Chociaż nie zawsze tworzy lepszy kod, w niektórych przypadkach programy skompilowane za pomocą gccgo mogą działać 30% szybciej.
Oczekuje się, że wydania GCC 7 będą zawierać pełną implementację bibliotek użytkownika Go 1.8. Podobnie jak w przypadku wcześniejszych wydań, środowisko wykonawcze Go 1.8 nie jest w pełni scalone, ale nie powinno to być widoczne dla programów Go.
Plusy:
Cons
go
.Możesz zobaczyć tutaj i tutaj .
źródło
gogcc
nie obsługuje procesora ARM, czy to prawda? Czy możesz zasugerować narzędzie, które zmniejszy rozmiar pliku kompilacji Golang?Bardziej zwarty przykład hello-world:
package main func main() { print("Hello world!") }
Ominęliśmy duży
fmt
pakiet i zauważalnie zmniejszono liczbę binarną:$ go build hello.go $ ls -lh hello ... 259K ... hello2 $ strip hello $ ls -lh hello ... 162K ... hello2
Nie tak kompaktowy jak C, ale mierzony w K, a nie w M :) Ok, nie jest to ogólny sposób, po prostu pokazuje kilka sposobów optymalizacji rozmiaru: użyj paska i spróbuj użyć minimalnych pakietów. W każdym razie Go nie jest językiem do tworzenia małych plików binarnych.
źródło
Możesz rzucić okiem na moje małe badania na ten temat: https://github.com/xaionaro/documentation/blob/master/golang/reduce-binary-size.md
Pokazuje krok po kroku, jak zredukować statyczną binarną próbkę hello-world o wielkości 2 MB do 15 KB statyczno-binarnych lub do 10 KB dynamicznie binarnych. Oczywiście jest wiele ograniczeń.
źródło
Odpowiedź 2018 na następną wersję Go 1.11, opublikowaną na Twitterze przez Brada Fitzpatricka (połowa czerwca 2018 r.):
Por. Wydanie Golang 11799 :
Zobacz więcej w commit 594eae5
Rob Pike wspomina :
Brad odpowiedział:
Powody : informacje o debugowaniu, ale także rejestracja mapy dla GC, aby każda instrukcja była punktem zapisu.
źródło
Domyślnie gcc łączy się dynamicznie i idzie - statycznie.
Ale jeśli połączysz swój kod C statycznie, możesz otrzymać plik binarny o większym rozmiarze.
W moim przypadku:
oba pliki binarne są połączone statycznie i bez debug_info.
go build -ldflags="-s -w" -o test-go test.go gcc -static -s -o test-c test.c
źródło
Plik binarny zawiera domyślnie moduł odśmiecania pamięci, system planowania, który zarządza procedurami go, oraz wszystkie importowane biblioteki.
Rezultatem jest minimalny rozmiar około 1 Mb.
źródło
Od wersji Go 1.8 możesz także użyć nowego systemu wtyczek, aby podzielić plik binarny na coś, co przypomina biblioteki współdzielone. W tej wersji działa tylko w systemie Linux, ale inne platformy będą prawdopodobnie obsługiwane w przyszłości.
https://tip.golang.org/pkg/plugin/
źródło