Hacker News new | ask | show | jobs
by firdak 3165 days ago
So, after "optimizations [...] to further reduce the resulting bundle size", a Java command-line "Hello World" is still 21.7 MB. I've found a Node.js version (using node-packer [1]) to be about the same size.

However, as mentioned in the article, "Hello World" in Go is an order of magnitude smaller. The article may be right that Java is "the best choice available" for cross-platform GUI apps, but for cross-platform command-line tools, I think Go is currently the best option. IMO Go provides the best tradeoff between ease of development, ease of distribution and runtime performance.

[1] https://github.com/pmq20/node-packer

4 comments

Since Go and Electron are mentioned, let me offer a web UI library for Go: https://github.com/zserge/webview (I know UI has been a problem for Go apps for a while and is often a stopper when it comes to writing desktop apps in Go).

The library creates a full-screen webview window and lets you write UI code in HTML5/CSS/JS connecting it to the core app logic written Go. It provides JS-to-Go bindings allowing to call Go code from JS and vice versa.

The whole library is a single header file of ~800LOC with a thin Go wrapper. It supports Windows 7+, MacOS, Linux and OpenBSD.

Executables are 5-10MB in size and take about the same amount of RAM. No external libraries are used on Windows and MacOS, on Linux gtk-webkit is required, but it is typically one "apt-get" command to run.

This looks pretty cool. I noticed on windows this uses mshtml. What browser tech does this use on windows 10?

Another question is around intercepting xls/doc responses to load them into office. Is there a way to do this with this framework?

Thanks!

On Windows 7 SP1 it uses IE11. Same on Windows 10. On some Windows 8 it might use IE10, which is still not that bad.

Sorry, can't tell much about xls/doc. It's aimed to be a web UI for your app. Normally, you app would be a web server then. So if you want to handle certain requests and open external apps - you surely can do it.

People need to stop comparing app sizes of "Hello World" apps and use a more real, more complete application as an example. One that does most of the things that one would do in the platform, for starters.

If we "compare by Hello World" then Assembly/handwritten bytecode would win, but what's the point?

2.17 MB is still enormous for a "hello world" binary.
No. 2.17 MB is NOT enormous. Usually there is no runtime library. In contrast, C or C++ runtime libraries can easily exceed that size. For example, vc_redist.x64.exe is 13.9 MB.
It's a matter of platform and the libraries that you're using.

After all, back in the days we had 360k floppy disks, and executable written in C which did much more than just printing out "Hello world" would fit comfortably into less than half of that.

Modern C and C++ runtimes are bloated, because a 2MB executable isn't considered huge anymore and dynamic linking is common.

But you can have a 5k static executable printing "hello world" on Linux if you just trade in your stdlibc to musl. People have also managed to use musl with Rust to produce pretty small executables: https://lifthrasiir.github.io/rustlog/why-is-a-rust-executab...

(Note: The size in the article is 21.7 MB, and not 2.17 MB!)

I just tried building a statically linked 'hello world' c++ program, and co-incidentally, the binary also happened to be 2.1 MB!

   #include <iostream>
   
   int main( int, const char *[] )
   {
      std::cout << "Hello World!" << std::endl;
      return 0;
   }

'g++ -static -o hello hello.cpp' produces a binary of 2191112 bytes (Linux x64). Stripping it of debug symbols leaves a 1.7 MB file.
Go runtime is included in the executable. C or C++ do not automatically do that when writing a simple "hello world" and compiling it into an executable. stdio isn't statically linked by default.

And when rid of debugging symbols, even when importing the fmt package :

    package main

    import "fmt"

    func main() {
        fmt.Print("Hello World")
    }
go build -ldflags "-s -w" hello.go

is 1.3MB .

Java and Node need to ship their own virtual machine while native code does not (others mentioned that runtime may be dynamically linked). VM startup time is ludicrously high compared to execution time of "userspace" code in CLI tool, making such rintimes no-go for CLI tools (except for web devs, apparently).