walles / moar

Moar is a pager. It's designed to just do the right thing without any configuration.
Other
587 stars 17 forks source link

build size #146

Closed ghost closed 6 months ago

ghost commented 10 months ago

currently I am using Slit:

https://github.com/tigrawap/slit

which has a good size:

> go build -ldflags -s
> Get-ChildItem
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2023-08-14  4:37 PM        2198528 slit.exe

I am interested in Moar, but I noticed it is much larger:

> go build -ldflags -s
> Get-ChildItem moar.exe
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2023-08-14  4:38 PM        6132736 moar.exe

2.7 times larger. did you have any interest in reducing the program size?

walles commented 10 months ago

Yes.

I recall doing some experiments but never got much of anywhere.

One thing is I want debug data in my binaries so that moar can print a stack trace if it panics, and that usually takes some space.

If you have any suggestions for getting the binaries smaller I'm all ears!

ghost commented 10 months ago

first culprit is usually here:

https://github.com/walles/moar/blob/848958dad029cbc66d5281ec79caf3d833b7293c/go.mod#L6-L11

if you see anything that can be killed, we can see about doing that. here is the one from Slit if it helps:

https://github.com/tigrawap/slit/blob/master/go.mod

walles commented 10 months ago

Possibly logrus.

I tried goweight to see what would help but: https://github.com/jondot/goweight/issues/23

Something like that would be good I think!

walles commented 10 months ago

I'm reading the below output as there being 1.8MB strings in the binary.

Can the Chroma grammars be that big? Chroma is needed though so that'd be hard to work with.

~/s/moar (master|✔) $ go tool nm -size -sort size moar|grep -v " U "|head -20
 120d5f8    1850752 R go:string.*
 1463120     951608 R runtime.esymtab
 1463120     951608 R runtime.pclntab
 1463120     951608 R runtime.symtab
 13d1378     419048 R go:func.*
 11c7540     286904 R runtime.types
 11c7540     286904 R runtime.rodata
 11c7540     286904 R _type:*
 116a200     101824 T github.com/alecthomas/chroma/v2/lexers.haxeRules
 158b860      92672 B runtime.mheap_
 157b760      65792 B runtime.trace
 1451dc0      65512 R github.com/alecthomas/chroma/v2/lexers.embedded.files
 1142880      53504 T github.com/alecthomas/chroma/v2/formatters.init
 118fa60      53152 T github.com/alecthomas/chroma/v2/lexers.rakuRules
 156a0c0      34944 D runtime.itabTableInit
 1553b00      26592 D runtime.firstmoduledata
 1449980      24768 R github.com/alecthomas/chroma/v2/styles.embedded.files
 1443fe0      22944 R runtime.modinfo.str
 143f0e0      20224 R github.com/dlclark/regexp2/syntax.(*parser).scanOptions.jump17
 110e780      18592 T github.com/dlclark/regexp2.(*runner).execute
go tool nm: signal: broken pipe
~/s/moar (master|✔) $

Ref: https://stackoverflow.com/questions/70764915/how-to-check-the-size-of-packages-linked-into-my-go-code

walles commented 9 months ago

Got some support for goweight, here's the list. Chroma is needed, not sure what else could go, go.mod doesn't contain many dependencies.

I think the most obvious win might be if Chroma could be converted to using https://pkg.go.dev/regexp rather than <github.com/dlclark/regexp2/syntax>.

~/s/moar (master|✔) [1]$ goweight .
   12 MB runtime
  5.4 MB github.com/alecthomas/chroma/v2/lexers
  2.9 MB reflect
  2.1 MB golang.org/x/sys/unix
  1.8 MB syscall
  1.5 MB github.com/alecthomas/chroma/v2
  1.5 MB github.com/dlclark/regexp2/syntax
  1.5 MB encoding/json
  1.3 MB time
  1.3 MB encoding/xml
  1.2 MB internal/abi
  1.1 MB os
  1.1 MB github.com/sirupsen/logrus
  993 kB github.com/walles/moar/m
  966 kB fmt
  944 kB regexp/syntax
  812 kB regexp
  802 kB internal/reflectlite
  799 kB github.com/dlclark/regexp2
  684 kB compress/flate
  665 kB internal/poll
  640 kB math
  609 kB strconv
  603 kB encoding/binary
  599 kB strings
  586 kB flag
  492 kB bytes
  488 kB os/exec
  484 kB github.com/walles/moar/twin
  464 kB sync
  455 kB unicode
  451 kB github.com/alecthomas/chroma/v2/formatters/svg
  450 kB github.com/alecthomas/chroma/v2/formatters
  399 kB bufio
  395 kB github.com/alecthomas/chroma/v2/formatters/html
  382 kB context
  363 kB io
  354 kB sort
  328 kB io/fs
  310 kB html
  290 kB golang.org/x/term
  265 kB runtime/internal/atomic
  258 kB github.com/alecthomas/chroma/v2/styles
  250 kB path/filepath
  237 kB sync/atomic
  236 kB log
  206 kB internal/godebug
  200 kB internal/bisect
  169 kB os/signal
  159 kB embed
  148 kB encoding/base64
  145 kB compress/gzip
  138 kB hash/crc32
  134 kB internal/syscall/unix
  111 kB math/bits
  106 kB internal/fmtsort
  104 kB internal/cpu
   84 kB internal/bytealg
   74 kB path
   71 kB errors
   66 kB unicode/utf8
   59 kB io/ioutil
   44 kB internal/testlog
   35 kB hash
   35 kB runtime/internal/sys
   25 kB unicode/utf16
   18 kB internal/godebugs
   14 kB internal/race
   13 kB encoding
   11 kB internal/safefilepath
   10 kB internal/itoa
  9.0 kB internal/goexperiment
  7.6 kB internal/goarch
  7.4 kB internal/coverage/rtcov
  6.4 kB runtime/internal/math
  6.1 kB internal/oserror
  5.5 kB internal/syscall/execenv
  3.7 kB internal/unsafeheader
  3.4 kB internal/goos
  3.1 kB log/internal
~/s/moar (master|✔) $
walles commented 6 months ago

I don't know what could be done here, closing.

If somebody has concrete suggestions, feel free to reopen and present those.