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

strings, builtin: remove strings.Builder.clear(), fix array.clear() not working in the JS backend #23992

Merged
merged 2 commits into from
Mar 22, 2025

Conversation

XiaoPangxie732
Copy link
Contributor

@XiaoPangxie732 XiaoPangxie732 commented Mar 20, 2025

Currently, strings.Builder has a function named clear() which clears the content by reallocating the backing array.

However, there is no need to reallocate the array. For example, in str() function, the backing array is simply trimmed to zero length.

Also, the array type itself has a clear() function which does the same as trim(0). This PR reuses the clear() function in the array by simply removing the clear() function in strings.Builder and replacing trim(0) with clear() which does the same thing.

This PR shouldn't break existing code

Copy link

Connected to Huly®: V_0.6-22385

@XiaoPangxie732
Copy link
Contributor Author

Seems there are some problems on the js backend 🤔 convert to draft for now

@XiaoPangxie732 XiaoPangxie732 marked this pull request as draft March 21, 2025 17:15
@XiaoPangxie732 XiaoPangxie732 force-pushed the remove_strings_builder_clear branch from b50df63 to bf37b2d Compare March 21, 2025 20:00
@XiaoPangxie732 XiaoPangxie732 force-pushed the remove_strings_builder_clear branch from bf37b2d to 7916510 Compare March 21, 2025 20:05
@XiaoPangxie732 XiaoPangxie732 marked this pull request as ready for review March 21, 2025 20:06
@XiaoPangxie732
Copy link
Contributor Author

XiaoPangxie732 commented Mar 21, 2025

There seems to be no clear() method in JS Arrays, so I use an approach grabbed from the internet
Not sure if it will work, as I don't know how to test .js.v files locally. Running v test vlib on my machine won't execute node

@XiaoPangxie732 XiaoPangxie732 changed the title strings: remove strings.Builder.clear() strings, builtin: remove strings.Builder.clear(), fix array.clear() not working in the JS backend Mar 21, 2025
@spytheman
Copy link
Member

What was the initial motivation for this change?
Code cleanup, performance improvement, or a bugfix?

@XiaoPangxie732
Copy link
Contributor Author

XiaoPangxie732 commented Mar 22, 2025

What was the initial motivation for this change?

Code cleanup, performance improvement, or a bugfix?

Initially it was a performance improvement to avoid reallocations when clearing string builders, and later I thought it would be more readable to use clear() than trim(0) and could avoid a index < a.len check. But CI then failed. I found that the reason is that array.clear() is badly implemented on the js backend, but I don't know much about js, so I just searched a way to clear it on the web, and I'm not sure if there's a better way to do it, sorry

@spytheman
Copy link
Member

Thank you 🙇🏻 .

@spytheman
Copy link
Member

With -prod, it is consistently faster:

#0 17:13:05 ^ remove_strings_builder_clear ~/v>./v run .github/workflows/compare_pr_to_master.v -prod
==================================================================================================
Current git branch: remove_strings_builder_clear, commit: 0ab646b
    Compiling new V executables from PR branch: remove_strings_builder_clear, commit: 0ab646b ...
CPU: 2.58s	Real: 2.78s	Elapsed: 0:02.78	RAM: 420316KB	./v -o vnew1 cmd/v
CPU: 2.58s	Real: 2.80s	Elapsed: 0:02.80	RAM: 420324KB	./vnew1 -o vnew2 cmd/v
CPU: 2.57s	Real: 2.80s	Elapsed: 0:02.80	RAM: 420324KB	./vnew2 -no-parallel -o vnew cmd/v
CPU: 0.16s	Real: 0.18s	Elapsed: 0:00.18	RAM: 44936KB	./vnew -no-parallel -o nhw_current.c examples/hello_world.v
CPU: 2.18s	Real: 2.39s	Elapsed: 0:02.39	RAM: 420348KB	./vnew -no-parallel -o nv_current.c cmd/v
CPU: 100.93s	Real: 103.88s	Elapsed: 1:43.88	RAM: 458432KB	./vnew -no-parallel -prod -o vnew_prod cmd/v
>Size of        nhw_current.c:      45226
>Size of         nv_current.c:    6301251
>Size of                 vnew:    9689821
>Size of            vnew_prod:    4054496
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
==================================================================================================
    Compiling old V executables from branch: master, commit: 20d7d97 ...
CPU: 2.56s	Real: 2.80s	Elapsed: 0:02.80	RAM: 420348KB	./v -o vold1 cmd/v
CPU: 2.56s	Real: 2.81s	Elapsed: 0:02.81	RAM: 420352KB	./vold1 -o vold2 cmd/v
CPU: 2.57s	Real: 2.81s	Elapsed: 0:02.81	RAM: 420320KB	./vold2 -no-parallel -o vold cmd/v
CPU: 0.16s	Real: 0.18s	Elapsed: 0:00.18	RAM: 44944KB	./vold -no-parallel -o ohw_master.c examples/hello_world.v
CPU: 2.18s	Real: 2.39s	Elapsed: 0:02.39	RAM: 420324KB	./vold -no-parallel -o ov_master.c cmd/v
CPU: 101.31s	Real: 104.05s	Elapsed: 1:44.05	RAM: 458820KB	./vold -no-parallel -prod -o vold_prod cmd/v
>Size of            vold_prod:    4087488
>Size of         ohw_master.c:      45226
>Size of          ov_master.c:    6301447
>Size of                 vold:    9690164
>Size of            vold_prod:    4087488
==================================================================================================
File sizes so far ...
>>>>>> size("  nhw_current.c") - size("   ohw_master.c") =      45226 -      45226 =          0
>>>>>> size("   nv_current.c") - size("    ov_master.c") =    6301251 -    6301447 =       -196
>>>>>> size("           vnew") - size("           vold") =    9689821 -    9690164 =       -343
Switched to branch 'remove_strings_builder_clear'
==================================================================================================
    Measuring at PR branch: remove_strings_builder_clear, commit: 0ab646b ...
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 1036.990 ms
    1   -0.4% 1.00x faster  42.2ms ± σ:   0.0ms,  42.1ms… 42.2ms `./vnew_prod -check-syntax           examples/hello_world.v`
 >  2         base          42.4ms ± σ:   0.1ms,  42.3ms… 42.5ms `./vold_prod -check-syntax           examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 1033.797 ms
 >  1         base          42.1ms ± σ:   0.1ms,  41.9ms… 42.3ms `./vold_prod -check-syntax           examples/hello_world.v`
    2   +0.1% 1.00x ~same~  42.2ms ± σ:   0.1ms,  42.1ms… 42.2ms `./vnew_prod -check-syntax           examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 1037.140 ms
    1   -0.7% 1.01x faster  42.2ms ± σ:   0.0ms,  42.1ms… 42.2ms `./vnew_prod -check-syntax           examples/hello_world.v`
 >  2         base          42.5ms ± σ:   0.1ms,  42.4ms… 42.5ms `./vold_prod -check-syntax           examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 1504.105 ms
    1   -0.5% 1.01x faster  61.1ms ± σ:   0.1ms,  61.0ms… 61.2ms `./vnew_prod -check                  examples/hello_world.v`
 >  2         base          61.5ms ± σ:   0.3ms,  61.1ms… 61.9ms `./vold_prod -check                  examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 1503.369 ms
    1   -0.0% 1.00x ~same~  61.2ms ± σ:   0.1ms,  61.1ms… 61.3ms `./vnew_prod -check                  examples/hello_world.v`
 >  2         base          61.2ms ± σ:   0.3ms,  60.9ms… 61.6ms `./vold_prod -check                  examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 1505.537 ms
    1   -0.5% 1.00x faster  61.2ms ± σ:   0.1ms,  61.0ms… 61.3ms `./vnew_prod -check                  examples/hello_world.v`
 >  2         base          61.4ms ± σ:   0.2ms,  61.2ms… 61.7ms `./vold_prod -check                  examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 1751.858 ms
    1   -0.3% 1.00x faster  71.4ms ± σ:   0.1ms,  71.3ms… 71.5ms `./vnew_prod -no-parallel -o nhw.c   examples/hello_world.v`
 >  2         base          71.6ms ± σ:   0.1ms,  71.5ms… 71.7ms `./vold_prod -no-parallel -o ohw.c   examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 1762.412 ms
    1   -0.2% 1.00x faster  71.8ms ± σ:   0.1ms,  71.6ms… 71.9ms `./vnew_prod -no-parallel -o nhw.c   examples/hello_world.v`
 >  2         base          71.9ms ± σ:   0.5ms,  71.3ms… 72.5ms `./vold_prod -no-parallel -o ohw.c   examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 1758.371 ms
    1   -0.1% 1.00x ~same~  71.7ms ± σ:   0.1ms,  71.6ms… 71.8ms `./vnew_prod -no-parallel -o nhw.c   examples/hello_world.v`
 >  2         base          71.8ms ± σ:   0.1ms,  71.7ms… 71.9ms `./vold_prod -no-parallel -o ohw.c   examples/hello_world.v`
>>>>>> size("          nhw.c") - size("          ohw.c") =      45226 -      45226 =          0
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 2060.428 ms
 >  1         base          84.0ms ± σ:   0.4ms,  83.4ms… 84.3ms `./vold_prod -no-parallel -o ohw.exe examples/hello_world.v`
    2   +0.1% 1.00x ~same~  84.1ms ± σ:   0.3ms,  83.6ms… 84.3ms `./vnew_prod -no-parallel -o nhw.exe examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 2062.197 ms
 >  1         base          84.0ms ± σ:   0.2ms,  83.8ms… 84.2ms `./vold_prod -no-parallel -o ohw.exe examples/hello_world.v`
    2   +0.3% 1.00x slower  84.2ms ± σ:   0.4ms,  83.8ms… 84.7ms `./vnew_prod -no-parallel -o nhw.exe examples/hello_world.v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 2066.973 ms
    1   -1.2% 1.01x faster  84.1ms ± σ:   0.4ms,  83.6ms… 84.5ms `./vnew_prod -no-parallel -o nhw.exe examples/hello_world.v`
 >  2         base          85.1ms ± σ:   0.1ms,  85.0ms… 85.2ms `./vold_prod -no-parallel -o ohw.exe examples/hello_world.v`
>>>>>> size("        nhw.exe") - size("        ohw.exe") =     252839 -     252839 =          0
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 8244.323 ms
    1   -1.0% 1.01x faster 339.7ms ± σ:   0.1ms, 339.6ms…339.8ms `./vnew_prod -check-syntax           cmd/v`
 >  2         base         343.1ms ± σ:   0.3ms, 342.7ms…343.4ms `./vold_prod -check-syntax           cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 8248.640 ms
    1   -1.0% 1.01x faster 339.8ms ± σ:   0.0ms, 339.8ms…339.9ms `./vnew_prod -check-syntax           cmd/v`
 >  2         base         343.4ms ± σ:   0.6ms, 342.6ms…344.0ms `./vold_prod -check-syntax           cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 8249.940 ms
    1   -1.0% 1.01x faster 339.8ms ± σ:   0.2ms, 339.6ms…340.1ms `./vnew_prod -check-syntax           cmd/v`
 >  2         base         343.3ms ± σ:   0.3ms, 342.9ms…343.7ms `./vold_prod -check-syntax           cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 13884.487 ms
    1   -0.3% 1.00x faster 574.9ms ± σ:   0.8ms, 573.8ms…575.7ms `./vnew_prod -check                  cmd/v`
 >  2         base         576.8ms ± σ:   1.1ms, 575.2ms…577.6ms `./vold_prod -check                  cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 13873.599 ms
    1   -0.4% 1.00x faster 574.6ms ± σ:   0.5ms, 574.2ms…575.4ms `./vnew_prod -check                  cmd/v`
 >  2         base         576.8ms ± σ:   0.3ms, 576.5ms…577.1ms `./vold_prod -check                  cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 13884.272 ms
    1   -0.3% 1.00x faster 575.4ms ± σ:   1.0ms, 573.9ms…576.2ms `./vnew_prod -check                  cmd/v`
 >  2         base         576.9ms ± σ:   0.4ms, 576.3ms…577.3ms `./vold_prod -check                  cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 22809.230 ms
    1   -0.0% 1.00x ~same~ 947.9ms ± σ:   0.6ms, 947.1ms…948.5ms `./vnew_prod -no-parallel -o nv.c    cmd/v`
 >  2         base         948.1ms ± σ:   0.1ms, 948.0ms…948.3ms `./vold_prod -no-parallel -o ov.c    cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 22808.732 ms
    1   -0.0% 1.00x ~same~ 947.8ms ± σ:   0.2ms, 947.6ms…948.1ms `./vnew_prod -no-parallel -o nv.c    cmd/v`
 >  2         base         947.9ms ± σ:   0.2ms, 947.7ms…948.1ms `./vold_prod -no-parallel -o ov.c    cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 22801.534 ms
    1   -0.1% 1.00x ~same~ 947.3ms ± σ:   0.1ms, 947.1ms…947.4ms `./vnew_prod -no-parallel -o nv.c    cmd/v`
 >  2         base         948.1ms ± σ:   0.1ms, 947.9ms…948.2ms `./vold_prod -no-parallel -o ov.c    cmd/v`
>>>>>> size("           nv.c") - size("           ov.c") =    6301251 -    6301251 =          0
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 1/3, took: 32480.288 ms
 >  1         base         1350.7ms ± σ:   0.2ms, 1350.4ms…1350.9ms `./vold_prod -no-parallel -o ov.exe  cmd/v`
    2   +0.1% 1.00x ~same~ 1351.8ms ± σ:   0.5ms, 1351.3ms…1352.4ms `./vnew_prod -no-parallel -o nv.exe  cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 2/3, took: 32480.947 ms
    1   -0.2% 1.00x faster 1348.8ms ± σ:   0.7ms, 1347.9ms…1349.4ms `./vnew_prod -no-parallel -o nv.exe  cmd/v`
 >  2         base         1352.0ms ± σ:   0.3ms, 1351.7ms…1352.3ms `./vold_prod -no-parallel -o ov.exe  cmd/v`
Summary after 1 series x 10 runs (%s are relative to first command, or `base`), discard maxs:  7, repeat: 3/3, took: 32474.411 ms
 >  1         base         1350.3ms ± σ:   0.5ms, 1349.6ms…1350.8ms `./vold_prod -no-parallel -o ov.exe  cmd/v`
    2   +0.0% 1.00x ~same~ 1350.6ms ± σ:   0.3ms, 1350.4ms…1351.1ms `./vnew_prod -no-parallel -o nv.exe  cmd/v`
>>>>>> size("         nv.exe") - size("         ov.exe") =    9689839 -    9689839 =          0
Done. Total time: 481.4140764 s.
==================================================================================================
Final summary for file diff sizes on their own branches:
>>>>>> size("  nhw_current.c") - size("   ohw_master.c") =      45226 -      45226 =          0
>>>>>> size("   nv_current.c") - size("    ov_master.c") =    6301251 -    6301447 =       -196
>>>>>> size("           vnew") - size("           vold") =    9689821 -    9690164 =       -343
>>>>>> size("      vnew_prod") - size("      vold_prod") =    4054496 -    4087488 =     -32992
==================================================================================================
Final summary for file diff sizes for generated files on the *current* branch:
>>>>>> size("          nhw.c") - size("          ohw.c") =      45226 -      45226 =          0
>>>>>> size("           nv.c") - size("           ov.c") =    6301251 -    6301251 =          0
>>>>>> size("        nhw.exe") - size("        ohw.exe") =     252839 -     252839 =          0
>>>>>> size("         nv.exe") - size("         ov.exe") =    9689839 -    9689839 =          0
#0 17:21:12 ^ remove_strings_builder_clear ~/v>

Without -prod (with tcc), it is consistently a bit slower (~0.5%) on my machine, which I do not understand fully yet.

@spytheman
Copy link
Member

In any case, the code is simpler now, so excellent work 🙇🏻‍♂️ .

@spytheman spytheman merged commit 15c0e6f into vlang:master Mar 22, 2025
72 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants