Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release article for nim 1.6.0 #301

Merged
merged 87 commits into from
Oct 4, 2021

Conversation

timotheecour
Copy link
Member

@timotheecour timotheecour commented Sep 26, 2021

notes for obtaining the stats:

  • nb of packages:
git clone https://github.com/nim-lang/packages
cd packages
jq '. | length' packages.json
1732

then do same as of the time of 1.4 release (16 October 2020) and subtract from that

nim --eval:'echo 1732-1452'
280
  • nb of commits since 1.4 release (f8890a0):
git rev-list f8890a0^..HEAD | wc -l
    1760

links

@timotheecour timotheecour marked this pull request as ready for review September 26, 2021 03:01
Copy link

@quantimnot quantimnot left a comment

Choose a reason for hiding this comment

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

Here are some minor changes. I was attempting to make everything a little more consistent.

jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
Copy link
Contributor

@ee7 ee7 left a comment

Choose a reason for hiding this comment

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

Some nitpicks.

jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved
jekyll/_posts/2021-09-25-version-160-released.md Outdated Show resolved Hide resolved

# Footnotes
Tested on a 2.3 GHz 8-Core Intel Core i9, 2019 macOS 11.5 with 64GB RAM.
* [1] command used: `nim c -o:/tmp/main -d:danger --eval:'echo "hello world"'`
Copy link
Contributor

@ee7 ee7 Sep 29, 2021

Choose a reason for hiding this comment

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

Suggested change
* [1] command used: `nim c -o:/tmp/main -d:danger --eval:'echo "hello world"'`
* [1] command used: `nim c -o:/tmp/main -d:danger --eval:'echo "hello world"'`.
Note that the Nim result is without optimizing for size (via `--opt:size`), without stripping (`--passL:-s`), and without using full link-time optimization (`--passC:-flto`).
It's also fairly straightforward to create a statically linked 5 kB "hello world" binary via musl, and you can get down to ~150 bytes with some extra tricks.

I think it's worth adding a couple of sentences here, as binary size is often a focus in reddit/HN comment threads. Feel free to adapt.

I've avoided -d:strip and -d:lto here, as they don't currently work reliably on every platform IIRC (macOS?).

For the "5 kB hello world binary": see e.g. https://irclogs.nim-lang.org/07-07-2020.html#12:31:34

Copy link
Member Author

Choose a reason for hiding this comment

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

@ee7 see commit update "small binaries" section ;

I didnt' mention and you can get down to ~150 bytes with some extra tricks. as I don't see where are those extra tricks mentioned; in particular https://irclogs.nim-lang.org/07-07-2020.html#12:31:34 mentions:

and if I disregard echo and use c_printf from system/ansi_c it's 5112 bytes

do you have more detail?

@Yardanico can you please confirm the 5K numbers for static linking with musl? on osx (without musl) i get the quoted 49K

Copy link

Choose a reason for hiding this comment

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

Sure, I'll check those numbers on Linux and Windows again to see how small will it be

Copy link

@ghost ghost Sep 30, 2021

Choose a reason for hiding this comment

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

@timotheecour it's better to discuss this matter in real-time chats I think, but here are the results for the Zig 0.8.1 released from Arch Linux repos + Nim 1.5.1 (6bb32da4aecbe80a9cc0cce90322c0e741ee8b85):
Nim source file:

echo "Hello, World!"

Compilation process:

$ nim c --os:any -d:posix -d:noSignalHandler --cc:clang --clang.exe="zigcc.sh" --clang.linkerexe="zigcc.sh" -d:danger --gc:arc -d:useMalloc --panics:on --passL:"-target x86_64-linux-musl -flto" --opt:size hello.nim
Hint: used config file '/home/dian/nim/config/nim.cfg' [Conf]
Hint: used config file '/home/dian/nim/config/config.nims' [Conf]
...................................................
Hint:  [Link]
Hint: gc: arc; opt: size; options: -d:danger
23293 lines; 0.350s; 25.414MiB peakmem; proj: /home/dian/test_bin_size/hello.nim; out: /home/dian/test_bin_size/hello [SuccessX]

$ strip -s -R .comment -R .note -R .note.ABI-tag hello

$ wc hello
  14  166 7296 hello

$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped

Result - a fully static binary with the size of 7296 bytes.

zigcc.sh is a shell script with the contents:

#!/usr/bin/env sh
zig cc $@

It's needed because Nim expects a name of the compiler binary and doesn't accept commands with spaces like zig cc.

I've also done a couple of tests with a few musl gcc toolchains, but the binary size with them is around 13KB even after stripping.

P.S.: Not sure if we should really specify the whole process for building a small binary, it'll be quite cumbersome to follow.

Copy link

@ghost ghost Sep 30, 2021

Choose a reason for hiding this comment

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

Without the --os:any -d:posix trickery the file size is 16976 bytes (for a Linux binary)

Copy link
Contributor

Choose a reason for hiding this comment

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

Result - a fully static binary with the size of 7296 bytes.

@Yardanico I get 4848 bytes for a echo "Hello, World! binary on a similar setup (x86_64; Arch Linux; Nim 1.5.1 recent commit; Zig 0.8.1).

It looks like you forgot this option: --passC:'-flto -target x86_64-linux-musl'.

The same thing, as a script:

#!/usr/bin/env sh
set -e
path_bin='./hello'

# Create source file
path_src="${path_bin}.nim"
rm -f "${path_src}"
echo 'echo "Hello, World!"' > "${path_src}"

# Compile
nim c -f \
  -d:danger --opt:size --gc:arc --panics:on \
  -d:useMalloc --os:any -d:posix -d:noSignalHandler \
  --cc=clang --clang.exe='zigcc.sh' --clang.linkerexe='zigcc.sh' \
  --passC:'-flto -target x86_64-linux-musl' \
  --passL:'-flto -target x86_64-linux-musl' \
  --skipUserCfg --skipParentCfg --skipProjCfg \
  "${path_bin}"

# Strip
strip --strip-all --remove-section=.comment "${path_bin}"

# Print some information about the binary
printf "\n"
file "${path_bin}"
byte_count="$(wc --bytes ${path_bin} | cut -d' ' -f1)"
echo "${byte_count} bytes"

# Show that the executable actually works
printf "\nRunning executable...\n"
"${path_bin}"
./hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
4848 bytes

Running executable...
Hello, World!

@narimiran narimiran mentioned this pull request Sep 30, 2021
@narimiran
Copy link
Member

Please move any further discussion and suggestions/improvements to #302, which has the updated version of this article.

@narimiran narimiran closed this Sep 30, 2021
@timotheecour
Copy link
Member Author

why move this to a different PR?

@narimiran
Copy link
Member

narimiran commented Sep 30, 2021

why move this to a different PR?

  1. It didn't feel right to push this big of a change to your branch.
  2. The diff would be useless (line reformatting, etc.).
  3. It is very hard to follow the discussion here — I get a notification of some new activity, but when I click it, it doesn't point to the new activity, I have to manually search what's new.
  4. If I try to expand any of the hidden stuff, my browser eats my CPU.

(@Yardanico raised similar concerns on Discord)


Once we have a final version, if you want, you can use that one and open a new PR, so it is correctly contributed to you.

@Araq Araq reopened this Oct 2, 2021
@Araq
Copy link
Member

Araq commented Oct 2, 2021

Reopening so that we can discuss how to proceed here but there were no malicious intentions.

@narimiran narimiran merged commit ef4cde6 into nim-lang:master Oct 4, 2021
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.