Skip to content

Conversation

@clipperhouse
Copy link
Contributor

Hi! I experimented with my graphemes package with your StringWidth and Truncate methods, and got some good results — considerably faster perf and lower allocs.

goos: darwin
goarch: arm64
pkg: github.com/mattn/go-runewidth
cpu: Apple M2
                                   │   old.txt    │              new.txt               │
                                   │    sec/op    │   sec/op     vs base               │
String1WidthAll/regular-8            108.63m ± 1%   41.51m ± 1%  -61.78% (p=0.002 n=6)
String1WidthAll/lut-8                 93.61m ± 1%   26.00m ± 0%  -72.23% (p=0.002 n=6)
String1Width768/regular-8             60.46µ ± 1%   15.80µ ± 0%  -73.87% (p=0.002 n=6)
String1Width768/lut-8                 60.69µ ± 0%   15.55µ ± 0%  -74.38% (p=0.002 n=6)
String1WidthAllEastAsian/regular-8   115.24m ± 1%   47.06m ± 0%  -59.16% (p=0.002 n=6)
String1WidthAllEastAsian/lut-8        93.62m ± 0%   26.02m ± 1%  -72.21% (p=0.002 n=6)
String1Width768EastAsian/regular-8    75.25µ ± 0%   27.99µ ± 1%  -62.81% (p=0.002 n=6)
String1Width768EastAsian/lut-8        60.79µ ± 0%   15.58µ ± 0%  -74.37% (p=0.002 n=6)
geomean                               2.559m        783.2µ       -69.40%

                                   │    old.txt     │               new.txt               │
                                   │      B/op      │     B/op      vs base               │
String1WidthAll/regular-8            106.251Mi ± 0%   4.250Mi ± 0%  -96.00% (p=0.002 n=6)
String1WidthAll/lut-8                106.251Mi ± 0%   4.250Mi ± 0%  -96.00% (p=0.002 n=6)
String1Width768/regular-8             75.000Ki ± 0%   3.000Ki ± 0%  -96.00% (p=0.002 n=6)
String1Width768/lut-8                 75.000Ki ± 0%   3.000Ki ± 0%  -96.00% (p=0.002 n=6)
String1WidthAllEastAsian/regular-8   106.251Mi ± 0%   4.250Mi ± 0%  -96.00% (p=0.002 n=6)
String1WidthAllEastAsian/lut-8       106.251Mi ± 0%   4.250Mi ± 0%  -96.00% (p=0.002 n=6)
String1Width768EastAsian/regular-8    75.000Ki ± 0%   3.000Ki ± 0%  -96.00% (p=0.002 n=6)
String1Width768EastAsian/lut-8        75.000Ki ± 0%   3.000Ki ± 0%  -96.00% (p=0.002 n=6)
geomean                                2.790Mi        114.3Ki       -96.00%

                                   │   old.txt   │              new.txt               │
                                   │  allocs/op  │  allocs/op   vs base               │
String1WidthAll/regular-8            3.342M ± 0%   1.114M ± 0%  -66.67% (p=0.002 n=6)
String1WidthAll/lut-8                3.342M ± 0%   1.114M ± 0%  -66.67% (p=0.002 n=6)
String1Width768/regular-8            2304.0 ± 0%    768.0 ± 0%  -66.67% (p=0.002 n=6)
String1Width768/lut-8                2304.0 ± 0%    768.0 ± 0%  -66.67% (p=0.002 n=6)
String1WidthAllEastAsian/regular-8   3.342M ± 0%   1.114M ± 0%  -66.67% (p=0.002 n=6)
String1WidthAllEastAsian/lut-8       3.342M ± 0%   1.114M ± 0%  -66.67% (p=0.002 n=6)
String1Width768EastAsian/regular-8   2304.0 ± 0%    768.0 ± 0%  -66.67% (p=0.002 n=6)
String1Width768EastAsian/lut-8       2304.0 ± 0%    768.0 ± 0%  -66.67% (p=0.002 n=6)
geomean                              87.75k        29.25k       -66.67%

Hopefully interesting!

@mattn
Copy link
Owner

mattn commented Sep 10, 2025

Thank you. I'll look into it in later.

@clipperhouse
Copy link
Contributor Author

Cheers. I just noticed this earlier conversation, with concern for compatibility with older Go versions.

This PR requires Go 1.20. I have another version in the works which can support Go 1.18, if it’s important.

@clipperhouse
Copy link
Contributor Author

Updated benchmarks, see benchstat.txt:

goos: darwin
goarch: arm64
pkg: github.com/mattn/go-runewidth
cpu: Apple M2
                                   │   old.txt    │              new.txt               │
                                   │    sec/op    │   sec/op     vs base               │
String1WidthAll/regular-8            108.92m ± 0%   35.09m ± 3%  -67.78% (p=0.002 n=6)
String1WidthAll/lut-8                 93.97m ± 0%   18.70m ± 0%  -80.10% (p=0.002 n=6)
String1Width768/regular-8             60.62µ ± 1%   11.54µ ± 0%  -80.97% (p=0.002 n=6)
String1Width768/lut-8                 60.66µ ± 1%   11.43µ ± 0%  -81.16% (p=0.002 n=6)
String1WidthAllEastAsian/regular-8   115.13m ± 1%   40.79m ± 8%  -64.57% (p=0.002 n=6)
String1WidthAllEastAsian/lut-8        93.65m ± 0%   18.70m ± 2%  -80.03% (p=0.002 n=6)
String1Width768EastAsian/regular-8    75.32µ ± 0%   23.49µ ± 0%  -68.82% (p=0.002 n=6)
String1Width768EastAsian/lut-8        60.76µ ± 0%   11.50µ ± 0%  -81.07% (p=0.002 n=6)
geomean                               2.562m        604.5µ       -76.41%

                                   │   old.txt    │                 new.txt                 │
                                   │     B/op     │    B/op      vs base                    │
String1WidthAll/regular-8            106.3Mi ± 0%    0.0Mi ± 0%  -100.00% (p=0.002 n=6)
String1WidthAll/lut-8                106.3Mi ± 0%    0.0Mi ± 0%  -100.00% (p=0.002 n=6)
String1Width768/regular-8            75.00Ki ± 0%   0.00Ki ± 0%  -100.00% (p=0.002 n=6)
String1Width768/lut-8                75.00Ki ± 0%   0.00Ki ± 0%  -100.00% (p=0.002 n=6)
String1WidthAllEastAsian/regular-8   106.3Mi ± 0%    0.0Mi ± 0%  -100.00% (p=0.002 n=6)
String1WidthAllEastAsian/lut-8       106.3Mi ± 0%    0.0Mi ± 0%  -100.00% (p=0.002 n=6)
String1Width768EastAsian/regular-8   75.00Ki ± 0%   0.00Ki ± 0%  -100.00% (p=0.002 n=6)
String1Width768EastAsian/lut-8       75.00Ki ± 0%   0.00Ki ± 0%  -100.00% (p=0.002 n=6)
geomean                              2.790Mi                     ?                      ¹ ²
¹ summaries must be >0 to compute geomean
² ratios must be >0 to compute geomean

                                   │   old.txt   │                 new.txt                 │
                                   │  allocs/op  │  allocs/op   vs base                    │
String1WidthAll/regular-8            3.342M ± 0%   0.000M ± 0%  -100.00% (p=0.002 n=6)
String1WidthAll/lut-8                3.342M ± 0%   0.000M ± 0%  -100.00% (p=0.002 n=6)
String1Width768/regular-8            2.304k ± 0%   0.000k ± 0%  -100.00% (p=0.002 n=6)
String1Width768/lut-8                2.304k ± 0%   0.000k ± 0%  -100.00% (p=0.002 n=6)
String1WidthAllEastAsian/regular-8   3.342M ± 0%   0.000M ± 0%  -100.00% (p=0.002 n=6)
String1WidthAllEastAsian/lut-8       3.342M ± 0%   0.000M ± 0%  -100.00% (p=0.002 n=6)
String1Width768EastAsian/regular-8   2.304k ± 0%   0.000k ± 0%  -100.00% (p=0.002 n=6)
String1Width768EastAsian/lut-8       2.304k ± 0%   0.000k ± 0%  -100.00% (p=0.002 n=6)
geomean                              87.75k                     ?                      ¹ ²
¹ summaries must be >0 to compute geomean
² ratios must be >0 to compute geomean

@mattn
Copy link
Owner

mattn commented Sep 29, 2025

I decided to merge this in later.

@mattn mattn merged commit 61f04f3 into mattn:master Sep 29, 2025
15 checks passed
@mattn
Copy link
Owner

mattn commented Sep 29, 2025

Thank you!

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