Skip to content

os: using CommandLineToArgv slows process startup significantly #15588

Closed
@jstarks

Description

@jstarks

Windows's os.init() calls syscall.CommandLineToArgv to split the Windows command line into separate arguments. This in turn loads shell32.dll and calls CommandLineToArgvW to do the actual work of splitting the command line. This is different from C programs generated by Microsoft's compiler, which use a nearly identical function in the CRT to do the splitting.

For a typical Go program, this is the only thing that causes shell32.dll to be loaded. Loading shell32 is expensive, since it depends on lots of additional DLLs -- on my machine shell32 loads 13 additional DLLs that would not otherwise be loaded.

By rewriting the algorithm from CommandLineToArgvW directly in go, we can eliminate the need to load all these extra DLLs. This algorithm is documented at https://msdn.microsoft.com/en-us/library/17w5ykft.aspx, although I have found that there is an undocumented special case where a " next to another " that ends a quoted argument should be included verbatim.

I have prototyped this change (3ae6766) and found on my machine that it reduces startup time for a simple Go program that pulls in os from 22ms to 16ms. The cost for this is about a 10KB increase in binary size.

If this approach seems worthwhile then I can send out a code review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.OS-Windows

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions