@sir minor: test-s reference is broken, should be "tests" in table.

@sir it would be a bit more fair to compare a single write() call in all cases. You know, write() isn't puts() isn't printf().

@jacereda @sir that'd give unfair languages who have direct libc or syscall bindings.

Eg. you can use write() from python by means of os.write, but that's non-idiomatic and would probably look suspicious in the middle of a larger program.

And then in some other interpreted language that's otherwise as slow as python but doesn't have such bindings, you'd have to use a generic print, which may be slower.

@jacereda one of my constraints is that I wouldn't write any code which was unidiomatic or would raise eyebrows in a code review

@sir Do you have a list which syscalls each binary calls?

@nifker no, but you can obtain one trivially with strace

@sir
Lua seems to be missing from the table even though its version is listed later.

how did you figure out the combined size for something like Java? just strace -f it and see what it looks at?

@grainloom fixed Lua

I took the lazy way out with Java tbh, it's just the installed size of the java runtime on my system

@sir valid metric tbh, i doubt anyone would go out of their way and only install parts of the stdlib

@sir I have yet to meet someone with strong feelings though which worries me.

@sir Well, it might make sense to compare top 10.

@sir I don't quite understand what you are trying to show. Surely, if one wants a binary that displays text on the console, probably the best way to do this is to write assembler. Some languages have a runtime that takes space and will get amortized. Scripting languages need to read the script. It all counts. Maybe it would make sense if you compared 1 print with 10, 20, 50, 100, etc. or with other functionality.

@sir @espectalll The ideal compiler would not do a syscall, but a single call to libc, though. syscalls are not stable on most OSes and the proper abstraction is libc. The idea of using syscalls directly is a Linuxism that unfortunately is widely spread in the Go community and resulted in binaries that break when you update your OS on e.g. macOS or OpenBSD. Please don’t spread the misinformation that it’s good to call syscalls directly.

@js @sir I mean, other than the assembly version I don't think any binary is not using a libc, I don't think that's the message AT ALL

@js @espectalll @sir Well it can avoid it, sure, with the correct build flags (don’t remember off the top of my head) but as soon as I used net package it turned it from a static binary into a libc-using dynamic binary.

You can tell it to build a static binary, in which case it starts to use its own DNS resolver and such. For my own use, that’s a downside as then it cannot resolve winbind or avahi hostnames, or user info provided from LDAP, or similar.

$ cat tmp.go

package main import ( "fmt" "net" ) func main() { net.Dial("tcp", "www.google.com:80") b := []byte{'A', 'b'} fmt.Printf("%s\n", b) }

$ ldd tmp

linux-vdso.so.1 (0x00007ffd04d83000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f92bceb3000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f92bccf3000) /lib64/ld-linux-x86-64.so.2 (0x00007f92bcef6000)

(Initial tmp.go didn’t have the use of net package so it actually did produce a static binary.)

Sign in to participate in the conversation
Mastodon

The social network of the future: No ads, no corporate surveillance, ethical design, and decentralization! Own your data with Mastodon!