Skip to content

Conversation

@metagn
Copy link
Collaborator

@metagn metagn commented Nov 7, 2025

While a.push.apply(a, b) is better for performance than the previous a = a.concat(b) due to the fact that it doesn't create a new array, there is a pretty big problem with it: depending on the JS engine, if the second array is too long, it can cause a crash due to the function push taking too many arguments. This has unfortunately been what the codegen produces since 1.4.0 (commit 707367e).

So string addition is now moved to a compilerproc that just uses a for loop. From what I can tell this is the most compatible and the fastest. Only potential problem compared to concat etc is with aliasing, i.e. adding an array to itself, but I'm guessing it's enough that the length from before the iteration is used, since it can only grow. The test checks for aliased nim strings but I don't know if there's an extra protection for them.

@Araq Araq added the merge_when_passes_CI mergeable once green label Nov 7, 2025
@ringabout ringabout merged commit 839cbeb into nim-lang:devel Nov 7, 2025
18 checks passed
@github-actions
Copy link
Contributor

github-actions bot commented Nov 7, 2025

Thanks for your hard work on this PR!
The lines below are statistics of the Nim compiler built from 839cbeb

Hint: mm: orc; opt: speed; options: -d:release
183325 lines; 8.348s; 661.727MiB peakmem

narimiran pushed a commit that referenced this pull request Nov 8, 2025
)

While `a.push.apply(a, b)` is better for performance than the previous
`a = a.concat(b)` due to the fact that it doesn't create a new array,
there is a pretty big problem with it: depending on the JS engine, if
the second array is too long, it can [cause a
crash](https://tanaikech.github.io/2020/04/20/limitation-of-array.prototype.push.apply-under-v8-for-google-apps-script/)
due to the function `push` taking too many arguments. This has
unfortunately been what the codegen produces since 1.4.0 (commit
707367e).

So string addition is now moved to a compilerproc that just uses a `for`
loop. From what I can tell this is the most compatible and the fastest.
Only potential problem compared to `concat` etc is with aliasing, i.e.
adding an array to itself, but I'm guessing it's enough that the length
from before the iteration is used, since it can only grow. The test
checks for aliased nim strings but I don't know if there's an extra
protection for them.

(cherry picked from commit 839cbeb)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge_when_passes_CI mergeable once green

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants