Description
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.