Comparemos cy vayamos: Hello_world.c:
#include<stdio.h>
int main(){
printf("Hello world!");
}
Hello_world.go:
package main
import "fmt"
func main(){
fmt.Printf("Hello world!")
}
Compila ambos:
$gcc Hello_world.c -o Hello_c
$8g Hello_world.go -o Hello_go.8
$8l Hello_go.8 -o Hello_go
¿Y qué es eso?
$ls -ls
... 5,4K 2010-10-05 11:09 Hello_c
... 991K 2010-10-05 11:17 Hello_go
Aproximadamente 1Mb Hola mundo. ¿Me estás tomando el pelo? ¿Qué hice mal?
(tira Hello_go -> 893K solamente)
Respuestas:
¿Es un problema que el archivo sea más grande? No sé Go, pero supongo que enlaza estáticamente alguna biblioteca en tiempo de ejecución, lo que no es el caso del programa C. Pero probablemente eso no sea nada de qué preocuparse tan pronto como su programa crezca.
Como se describe aquí , la vinculación estática del tiempo de ejecución de Go es la opción predeterminada. Esa página también le indica cómo configurar los enlaces dinámicos.
fuente
Si está utilizando un sistema basado en Unix (por ejemplo, Linux o Mac OSX), puede intentar eliminar la información de depuración incluida en el ejecutable compilándolo con el indicador -w:
go build -ldflags "-w" prog.go
Los tamaños de archivo se reducen drásticamente.
Para obtener más detalles, visite la página del BGF: http://golang.org/doc/gdb
fuente
strip
comando:go build prog.go; strip prog
luego obtuvimos el llamado ejecutable rayado : ejecutable LSB ELF de 64 bits, x86-64, versión 1 (SYSV), vinculado dinámicamente (usa bibliotecas compartidas), eliminado-w
, en lugar de-s
. No estoy seguro de cuál es la diferencia, pero es posible que desee actualizar su respuesta :-)La respuesta de 2016:
1. Utilice Go 1.7
2. Compilar con
go build -ldflags "-s -w"
➜ ls -lh hello -rwxr-xr-x 1 oneofone oneofone 976K May 26 20:49 hello*
3. Luego use
upx
,goupx
ya no es necesario desde 1.6.➜ ls -lh hello -rwxr-xr-x 1 oneofone oneofone 367K May 26 20:49 hello*
fuente
Los binarios de Go son grandes porque están vinculados estáticamente (a excepción de los enlaces de biblioteca que utilizan cgo). Intente vincular estáticamente un programa en C y verá que crece a un tamaño comparable.
Si esto es realmente un problema para usted (que me cuesta creer), puede compilar con gccgo y vincular dinámicamente.
fuente
Debería obtener goupx , "arreglará" los ejecutables de Golang ELF para trabajar
upx
. Ya tengo una reducción del tamaño de archivo de alrededor del 78% en algunos casos~16MB >> ~3MB
.La relación de compresión suele ser del 25%, por lo que vale la pena intentarlo:
$ 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: la
-s
bandera (tira) puede encoger aún más el archivo bingoupx -s filename
fuente
cree un archivo llamado
main.go
, intentemos con un programa simple de hola mundo.package main import "fmt" func main(){ fmt.Println("Hello World!") }
Yo uso go versión 1.9.1
$ go version go version go1.9.1 linux/amd64
Compile con
go build
comando estándar .$ go build main.go $ ls -lh -rwxr-xr-x-x 1 nil nil 1.8M Oct 27 07:47 main
Compilemos una vez más con
go build
pero conldflags
como se sugirió anteriormente,$ go build -ldflags "-s -w" main.go $ ls -lh -rwxr-xr-x-x 1 nil nil 1.2M Oct 27 08:15 main
El tamaño del archivo se reduce en un 30%.
Ahora, usemos
gccgo
,$ go version go version go1.8.1 gccgo (GCC) 7.2.0 linux/amd64
La construcción de ir con
gccgo
,$ go build main.go $ ls -lh -rwxr-xr-x 1 nil nil 34K Oct 27 12:18 main
El tamaño binario se reduce casi en un 100%. Intentemos una vez más construir nuestro
main.go
congccgo
pero con banderas de compilación,$ go build -gccgoflags "-s -w" main.go -rwxr-xr-x 1 nil nil 23K Oct 27 13:02 main
Advertencia: ya que los
gccgo
binarios se vincularon dinámicamente. Si tiene un binario que es muy grande en tamaño, su binario cuando se compila con gccgo no se reducirá en un 100%, pero se reducirá en tamaño en una cantidad considerable.En comparación con gc, gccgo es más lento para compilar código pero admite optimizaciones más potentes, por lo que un programa vinculado a la CPU creado por gccgo generalmente se ejecutará más rápido. Todas las optimizaciones implementadas en GCC a lo largo de los años están disponibles, incluida la inserción, las optimizaciones de bucle, la vectorización, la programación de instrucciones y más. Si bien no siempre produce un mejor código, en algunos casos los programas compilados con gccgo pueden ejecutarse un 30% más rápido.
Se espera que las versiones de GCC 7 incluyan una implementación completa de las bibliotecas de usuario de Go 1.8. Al igual que con versiones anteriores, el tiempo de ejecución de Go 1.8 no está completamente combinado, pero eso no debería ser visible para los programas de Go.
Pros:
Contras
go
.Puedes ver aquí y aquí .
fuente
gogcc
no es compatible con el procesador ARM, ¿verdad? Y, ¿puede sugerir una herramienta que reduzca el tamaño del archivo de compilación de Golang?Ejemplo de hello-world más compacto:
package main func main() { print("Hello world!") }
Somos grandes
fmt
paquetes esquiados y binarios notablemente reducidos:$ go build hello.go $ ls -lh hello ... 259K ... hello2 $ strip hello $ ls -lh hello ... 162K ... hello2
No tan compacto como C, pero aunque medido en K, no en M :) Ok, no es una forma general, solo muestra algunas formas de optimizar un tamaño: use strip e intente usar paquetes mínimos. De todos modos, Go no es un lenguaje para hacer binarios de tamaño pequeño.
fuente
2018 respuesta para la próxima Go 1.11, como tuiteó por Brad Fitzpatrick (mediados de junio de 2018):
Cf. Problema de Golang 11799 :
Ver más en el compromiso 594eae5
Rob Pike menciona :
Brad respondió:
Motivos : depure la información, pero también registre el mapa para que el GC permita que cualquier instrucción sea un punto de guardado.
fuente
El binario contiene de forma predeterminada el recolector de basura, el sistema de programación que administra las rutinas de marcha y todas las bibliotecas que importa.
El resultado es un tamaño mínimo de aproximadamente 1 Mb.
fuente
Desde Go 1.8 también puede usar el nuevo sistema de complementos para dividir su binario en algo que se parezca a bibliotecas compartidas. Para esta versión, solo funciona en Linux, pero probablemente se admitirán otras plataformas en el futuro.
https://tip.golang.org/pkg/plugin/
fuente
Puede echar un vistazo a mi pequeña investigación sobre este tema: https://github.com/xaionaro/documentation/blob/master/golang/reduce-binary-size.md
Muestra paso a paso cómo reducir una muestra binaria estática hello-world de 2MiB a 15KiB estática-binaria o a 10KiB dinámica-binaria. Por supuesto que existen muchas limitaciones.
fuente
Por defecto, gcc enlaza dinámicamente y va - estáticamente.
Pero si enlaza su código C de forma estática, puede obtener un binario con un tamaño mayor.
En mi caso:
ambos binarios están vinculados estáticamente y sin debug_info.
go build -ldflags="-s -w" -o test-go test.go gcc -static -s -o test-c test.c
fuente