Thanks to visit codestin.com
Credit goes to github.com

Skip to content

build: omit DWARF tables by default#1937

Merged
ttaylorr merged 5 commits into
masterfrom
no-dwarf-tables
Feb 14, 2017
Merged

build: omit DWARF tables by default#1937
ttaylorr merged 5 commits into
masterfrom
no-dwarf-tables

Conversation

@ttaylorr

@ttaylorr ttaylorr commented Feb 14, 2017

Copy link
Copy Markdown
Contributor

This pull-request adds the --dwarf flag to script/bootstrap, and excludes DWARF tables from the compiled binaries by default.

Here are some ✨ metrics comparing the sizes of our binaries before/after:

Building a single (compressed) binary with DWARF tables:

~/g/git-lfs (scratch/no-dwarf-tables) $ ./script/bootstrap --dwarf && gzip < ./bin/git-lfs | wc -c
commands/mancontent_gen.go
Using go1.8rc3
 3434387

Building a single (compressed) binary without DWARF tables:

~/g/git-lfs (scratch/no-dwarf-tables) $ ./script/bootstrap && gzip < ./bin/git-lfs | wc -c
commands/mancontent_gen.go
Using go1.8rc3
 2673122

This shaves 22% (761265 bytes -> .76 MB) off of the compressed binaries. I ran some tests against all of the platforms/architectures we build for, and the average size reduction of the compressed releases was

darwin-386 darwin-amd64 freebsd-386 freebsd-amd64 linux-386 linux-amd64 windows-386 windows-amd64
3213504 3446603 3229616 3443504 3225807 3443145 3212684 3436845
2473611 2685306 2345922 2540355 2344751 2540280 2348202 2548085
-23.02% -22.09% -27.36% -26.23% -27.31% -26.22% -26.91% -25.86%

With an average of a -25.63% reduction in compressed size.

A couple of notes:

  1. I made omitting the DWARF tables the default behavior for script/bootstrap, since that's the way we'll build it for release, I think we should be as close to that as possible in development/test environments. I don't use dlv often with LFS, but if you need to have the debugger symbols, you can always re-run script/bootstrap with the --dwarf flag.
  2. I chose to skip further compression with upx[1] which seems to yield an average compression of about 15-25%. Though this would further reduce the size, it would increase the startup time by anywhere from 15-160msec. A while ago, @technoweenie stated his concern in Add support for Git LFS git-for-windows/build-extra#110 (comment):

I don't want to do anything that increases startup time (such as upx compression), since the default configuration using git clean/smudge filters can call the git-lfs binary many times on large repositories. But, we can probably live without debugging.

Before merging, I'd like to revisit this point to see if it's still the case with the process filter being more prominent and startup cost being less of a concern. Personally, I'd avoid further compression with upx or similar since even the minimum of 15ms extra to launch a command seems like too much to me. Additionally, for users still rocking the legacy single-process clean/smudge filters, the overhead would be much more noticeable during large checkouts.


/cc @git-lfs/core @dscho

@ttaylorr ttaylorr added this to the v2.0.0 milestone Feb 14, 2017
Comment thread script/build.go
))
}
if !*BuildDwarf || *BuildAll {
LdFlags = append(LdFlags, "-s", "-w")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it really make sense to only use -s, -w for BuildAll? From the outside, it's probably hard to comprehend why builds for a single platform are suddenly not stripped.

IMO the current default should be to always strip, regardless of BuildAll, unless BuildDwarf is given. And while at it, I'd probably rename BuildDwarf to something like BuildDebug.

If that turns out to be inconvenient during development, invert the logic and to not strip by default unless a BuildRelease is given, independently of BuildAll being given or not.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this is an artifact of when I was playing around with the command before I pushed the PR. At this stage, the flag was --no-dwarf, so the absence of it would include the DWARF tables by default. I wanted --all to be the equivalent of --all --no-dwarf without having to type that every time.

Since the flag is now --dwarf, I went ahead and removed that implicit behavior in 5f18308. Thanks for pointing this out!

@sinbad

sinbad commented Feb 14, 2017

Copy link
Copy Markdown
Contributor

Does this reduce stack trace visibility at all, for when chasing down panic bugs reported from the community that we may not be able to reproduce?

@technoweenie

Copy link
Copy Markdown
Contributor

Personally, I'd avoid further compression with upx or similar since even the minimum of 15ms extra to launch a command seems like too much to me.

I agree. Not worth it to have a binary about 500k smaller. This looks fine to me, but I, like @sinbad, would like to see how stack traces compare on this build.

@ttaylorr

Copy link
Copy Markdown
Contributor Author

@sinbad @technoweenie great question. I did test out some example stack traces when playing around with this locally, I just forgot to include them in the original pull-request. Here they are, with and without the DWARF tables:

With DWARF tables ~/g/git-lfs (no-dwarf-tables) $ ./script/bootstrap --dwarf && ./bin/git-lfs logs boomtown commands/mancontent_gen.go Using go1.8rc3 Welcome to Boomtown

Errors logged to /Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/.git/lfs/objects/logs/20170214T092505.376310742.log
Use git lfs logs last to view the log.
~/g/git-lfs (no-dwarf-tables) $ ./bin/git-lfs logs last
git-lfs/1.5.0 (GitHub; darwin amd64; go 1.8rc3; git 5f183083)
git version 2.11.1

$ git-lfs logs boomtown
Welcome to Boomtown

Error: Inner error message!
github.com/git-lfs/git-lfs/errors.newWrappedError
/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/errors/types.go:166
github.com/git-lfs/git-lfs/errors.Wrapf
/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/errors/errors.go:85
github.com/git-lfs/git-lfs/commands.logsBoomtownCommand
/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/commands/command_logs.go:56
github.com/git-lfs/git-lfs/vendor/github.com/spf13/cobra.(*Command).execute
/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/vendor/github.com/spf13/cobra/command.go:477
github.com/git-lfs/git-lfs/vendor/github.com/spf13/cobra.(*Command).Execute
/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/vendor/github.com/spf13/cobra/command.go:551
github.com/git-lfs/git-lfs/commands.Run
/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/commands/run.go:68
main.main
/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/git-lfs.go:35
runtime.main
/usr/local/Cellar/go/1.8rc3/libexec/src/runtime/proc.go:185
runtime.goexit
/usr/local/Cellar/go/1.8rc3/libexec/src/runtime/asm_amd64.s:2197

ENV:
LocalWorkingDir=/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs
LocalGitDir=/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/.git
LocalGitStorageDir=/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/.git
LocalMediaDir=/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/.git/lfs/objects
LocalReferenceDir=
TempDir=/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/.git/lfs/tmp
ConcurrentTransfers=3
TusTransfers=false
BasicTransfersOnly=false
BatchTransfer=true
SkipDownloadErrors=false
FetchRecentAlways=false
FetchRecentRefsDays=7
FetchRecentCommitsDays=0
FetchRecentRefsIncludeRemotes=true
PruneOffsetDays=3
PruneVerifyRemoteAlways=false
PruneRemoteName=origin
AccessDownload=none
AccessUpload=none
DownloadTransfers=basic
UploadTransfers=basic

Without DWARF tables ~/g/git-lfs (no-dwarf-tables) $ ./script/bootstrap && ./bin/git-lfs logs boomtown commands/mancontent_gen.go Using go1.8rc3 Welcome to Boomtown

Errors logged to /Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/.git/lfs/objects/logs/20170214T092551.184256199.log
Use git lfs logs last to view the log.
~/g/git-lfs (no-dwarf-tables) $ ./bin/git-lfs logs last
git-lfs/1.5.0 (GitHub; darwin amd64; go 1.8rc3; git 5f183083)
git version 2.11.1

$ git-lfs logs boomtown
Welcome to Boomtown

Error: Inner error message!
github.com/git-lfs/git-lfs/errors.newWrappedError
/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/errors/types.go:166
github.com/git-lfs/git-lfs/errors.Wrapf
/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/errors/errors.go:85
github.com/git-lfs/git-lfs/commands.logsBoomtownCommand
/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/commands/command_logs.go:56
github.com/git-lfs/git-lfs/vendor/github.com/spf13/cobra.(*Command).execute
/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/vendor/github.com/spf13/cobra/command.go:477
github.com/git-lfs/git-lfs/vendor/github.com/spf13/cobra.(*Command).Execute
/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/vendor/github.com/spf13/cobra/command.go:551
github.com/git-lfs/git-lfs/commands.Run
/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/commands/run.go:68
main.main
/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/git-lfs.go:35
runtime.main
/usr/local/Cellar/go/1.8rc3/libexec/src/runtime/proc.go:185
runtime.goexit
/usr/local/Cellar/go/1.8rc3/libexec/src/runtime/asm_amd64.s:2197

ENV:
LocalWorkingDir=/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs
LocalGitDir=/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/.git
LocalGitStorageDir=/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/.git
LocalMediaDir=/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/.git/lfs/objects
LocalReferenceDir=
TempDir=/Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/.git/lfs/tmp
ConcurrentTransfers=3
TusTransfers=false
BasicTransfersOnly=false
BatchTransfer=true
SkipDownloadErrors=false
FetchRecentAlways=false
FetchRecentRefsDays=7
FetchRecentCommitsDays=0
FetchRecentRefsIncludeRemotes=true
PruneOffsetDays=3
PruneVerifyRemoteAlways=false
PruneRemoteName=origin
AccessDownload=none
AccessUpload=none
DownloadTransfers=basic
UploadTransfers=basic


And a diff between the two:

--- /Users/ttaylorr/Desktop/with-dwarf  2017-02-14 09:29:41.000000000 -0700
+++ /Users/ttaylorr/Desktop/without-dwarf       2017-02-14 09:29:47.000000000 -0700
@@ -1,6 +1,6 @@
 Welcome to Boomtown

-Errors logged to /Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/.git/lfs/objects/logs/20170214T092505.376310742.log
+Errors logged to /Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/.git/lfs/objects/logs/20170214T092551.184256199.log
 Use `git lfs logs last` to view the log.
 ~/g/git-lfs (no-dwarf-tables) $ ./bin/git-lfs logs last
 git-lfs/1.5.0 (GitHub; darwin amd64; go 1.8rc3; git 5f183083)

Since they're the same, I think that this pull-request is ready to go.

@sinbad sinbad left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one fix needed that isn't a bug now but might be depending on future use. 👍

Comment thread script/build.go
if len(LdFlag) > 0 {
args = append(args, "-ldflags", LdFlag)
if len(LdFlags) > 0 {
args = append(args, "-ldflags", strings.Join(LdFlags, " "))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The manual joining into 1 arg could possibly have some quoting issues in the future, I suggest instead:

args = append(args, "-ldflags")
args = append(args, LdFlags...)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is quite how the -ldflags flag works in practice. The -ldflags expects a string rather than introducing a set of arguments. Applying this change yields an empty ldflags set, and instead tries to pass the contents of LdFlags as packages for go build to build.

~/g/git-lfs (no-dwarf-tables!) $ ./script/bootstrap && gzip < bin/git-lfs | wc -c
Using go1.8rc3
can't load package: package github.com/git-lfs/git-lfs/config.GitCommit=5f183083: cannot find package "github.com/git-lfs/git-lfs/config.GitCommit=5f183083" in any of:
        /usr/local/Cellar/go/1.8rc3/libexec/src/github.com/git-lfs/git-lfs/config.GitCommit=5f183083 (from $GOROOT)
        /Users/ttaylorr/go/src/github.com/git-lfs/git-lfs/config.GitCommit=5f183083 (from $GOPATH)
can't load package: package -s: cannot find package "-s" in any of:
        /usr/local/Cellar/go/1.8rc3/libexec/src/-s (from $GOROOT)
        /Users/ttaylorr/go/src/-s (from $GOPATH)
can't load package: package -w: cannot find package "-w" in any of:
        /usr/local/Cellar/go/1.8rc3/libexec/src/-w (from $GOROOT)
        /Users/ttaylorr/go/src/-w (from $GOPATH)
can't load package: package -o: cannot find package "-o" in any of:
        /usr/local/Cellar/go/1.8rc3/libexec/src/-o (from $GOROOT)
        /Users/ttaylorr/go/src/-o (from $GOPATH)
can't load package: package bin/git-lfs: cannot find package "bin/git-lfs" in any of:
        /usr/local/Cellar/go/1.8rc3/libexec/src/bin/git-lfs (from $GOROOT)
        /Users/ttaylorr/go/src/bin/git-lfs (from $GOPATH)

2017/02/14 10:02:12 exit status 1
exit status 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, you're right, my bad - forgot that -ldflags was its own nested beast. I guess we just deal with any quoting issues manually if/when they occur then.

@dscho

dscho commented Feb 14, 2017

Copy link
Copy Markdown
Contributor

@ttaylorr thanks for doing this.

FWIW my wish is really only to keep Git for Windows' installer as lean as possible, therefore I have no qualm about including an unpacked git-lfs.exe as long as it compresses well ;-) Please also keep in mind that we're using LZMA compression in the Git for Windows installer, which in general outperforms GZIP in terms of size.

Would you have a built git-lfs.exe for me to play with (read: to build a test installer and see how much larger it gets)?

@ttaylorr

Copy link
Copy Markdown
Contributor Author

@dscho my pleasure. Here are both AMD64 and 386 builds with and without the DWARF tables. I'd build the installer for you myself, but I blew away my Windows VM!

git-lfs-windows-386-1.5.0-dwarf.zip
git-lfs-windows-386-1.5.0-no-dwarf.zip
git-lfs-windows-amd64-1.5.0-dwarf.zip
git-lfs-windows-amd64-1.5.0-no-dwarf.zip

@ttaylorr ttaylorr merged commit d9833cd into master Feb 14, 2017
@ttaylorr ttaylorr deleted the no-dwarf-tables branch February 14, 2017 18:13
@dscho

dscho commented Feb 16, 2017

Copy link
Copy Markdown
Contributor

Thanks, @ttaylorr.

I tested this by re-generating the (LZMA-compressing) Git for Windows installer with the current binaries, then adding no-DWARF git-lfs.exe and then adding DWARF git-lfs.exe instead. The respective sizes are: 35,628,610 bytes, 37,401,645 bytes and 38,071,549 bytes. That means that you managed to squash down a 6.9% increase just below 5%, which makes me comfortable enough to include Git LFS in the next Git for Windows version.

BTW is it intentional that you bundled v1.5.0 versions instead of v1.5.5 ones? When I compare the v1.5.5 release to the ones you provided, I see 3,200,602 (v1.5.5) vs 7,005,184 (v1.5.0, no-DWARF) vs 10,521,088 (v1.5.0, DWARF). Those are rather dramatic differences there... Do you have any idea why?

@ttaylorr

Copy link
Copy Markdown
Contributor Author

That means that you managed to squash down a 6.9% increase just below 5%, which makes me comfortable enough to include Git LFS in the next Git for Windows version.

🎉

BTW is it intentional that you bundled v1.5.0 versions instead of v1.5.5 ones?

Our release-1.5 branch is diverged from master, so the "version" on master is still 1.5.0. I gave you the latest build off of master, it's just named oddly.

@sschuberth

Copy link
Copy Markdown
Member

But why are there so big differences in the sizes between the versions?

@ttaylorr

Copy link
Copy Markdown
Contributor Author

But why are there so big differences in the sizes between the versions?

Sorry, I'm not sure what the size difference is caused by. Here are the numbers that I get:

  • 1.5.6 (DWARF): 3246752
  • 1.5.6 (without DWARF): 2528025
  • 2.0-pre (DWARF): 3438418
  • 2.0-pre (without DWARF): 2677118

@dscho

dscho commented Feb 17, 2017

Copy link
Copy Markdown
Contributor

@ttaylorr I was referring to the file sizes of the git-lfs.exe executables unpacked from the .zip files you so nicely provided for me...

Also, I uploaded git-lfs v1.5.6 to our Pacman repository (which is MSYS2's equivalent to Homebrew, kinda). But that release does not have your size improvement yet. Any idea which git-lfs version will have them?

@ttaylorr

Copy link
Copy Markdown
Contributor Author

Also, I uploaded git-lfs v1.5.6 to our Pacman repository (which is MSYS2's equivalent to Homebrew, kinda). But that release does not have your size improvement yet.

The release-1.5 branch (which we use to release all patch releases against 1.5), has diverged from master, and this pull-request was not backported to that release.

The next release (v2.0.0) will include this change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants