diff --git a/bench/fstw.mjs b/bench/fstw.mjs index dbe504e..9627ade 100644 --- a/bench/fstw.mjs +++ b/bench/fstw.mjs @@ -2,7 +2,7 @@ import _string_width from '../node_modules/fast-string-truncated-width/dist/inde const string_width = (input) => _string_width(input, {limit:Infinity, ellipsis:""}).width let sum = 0; -for(let i = 0; i < 10000; ++i) { +for(let i = 0; i < 100000; ++i) { sum += string_width("\x1b[1;95mยท \x1b[0m\x1b[K\x1b[33mdeno\x1b[0m\x1b[K, \x1b[33mtypescript\x1b[0m\x1b[K, \x1b[33mts\x1b[0m\x1b[K") } console.log(sum) diff --git a/bench/sw.mjs b/bench/sw.mjs index 0672867..cf2ee17 100644 --- a/bench/sw.mjs +++ b/bench/sw.mjs @@ -2,8 +2,9 @@ import { line as string_width, HandleGraphemeClusters } from '../build/dev/javas import { toList } from '../build/dev/javascript/string_width/gleam.mjs' let sum = 0; -let options = toList([new HandleGraphemeClusters()]); -for(let i = 0; i < 10000; ++i) { +// let options = toList([new HandleGraphemeClusters()]); +let options = toList([]) +for(let i = 0; i < 100000; ++i) { sum += string_width("\x1b[1;95mยท \x1b[0m\x1b[K\x1b[33mdeno\x1b[0m\x1b[K, \x1b[33mtypescript\x1b[0m\x1b[K, \x1b[33mts\x1b[0m\x1b[K", options) } console.log(sum) diff --git a/package-lock.json b/package-lock.json index 241245b..5f330a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,9 +7,9 @@ "dependencies": { "fast-string-truncated-width": "^1.1.0", "graphemer": "^1.4.0", - "string-width": "^7.2.0" - }, - "devDependencies": {} + "string-width": "^7.2.0", + "unicode-segmenter": "^0.10.1" + } }, "node_modules/ansi-regex": { "version": "6.1.0", @@ -78,6 +78,12 @@ "funding": { "url": "https://github.com/chalk/strip-ansi?sponsor=1" } + }, + "node_modules/unicode-segmenter": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/unicode-segmenter/-/unicode-segmenter-0.10.1.tgz", + "integrity": "sha512-SZzvUb3Unf9PeCcac8D6rTkfanyfUa1riRjW4ZTUvBIB69n09/U7TLsn6m9HEMaq1YHae2JENgF1LPolk3vZYQ==", + "license": "MIT" } } } diff --git a/package.json b/package.json index 61b069f..06c3e6b 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "dependencies": { "fast-string-truncated-width": "^1.1.0", "graphemer": "^1.4.0", - "string-width": "^7.2.0" + "string-width": "^7.2.0", + "unicode-segmenter": "^0.10.1" } } diff --git a/probe/pop-adapted.mjs b/probe/pop-adapted.mjs new file mode 100644 index 0000000..2ff06dc --- /dev/null +++ b/probe/pop-adapted.mjs @@ -0,0 +1,10 @@ +import { Segmenter } from 'unicode-segmenter/intl-adapter'; + +const str = "๐Ÿ˜€".repeat(10) + +let sum = 0 +const segmenter = new Segmenter() +for(let i = 0; i < 100000; ++i) { + sum += segmenter.segment(str)[Symbol.iterator]().next().value.segment.length +} +console.log(sum) diff --git a/probe/pop-improved.js b/probe/pop-improved.js new file mode 100644 index 0000000..a38cc2b --- /dev/null +++ b/probe/pop-improved.js @@ -0,0 +1,15 @@ +const str = "๐Ÿ˜€".repeat(100) + +const segmenter = new Intl.Segmenter(); +function fold_graphemes(str, state, fun) { + for (const { segment: grapheme } of segmenter.segment(str)) { + state = fun(grapheme, state) + } + return state +} + +let sum = 0 +for(let i = 0; i < 100000; ++i) { + sum += fold_graphemes(str, 0, (a, b) => b + a.length) +} +console.log(sum) diff --git a/probe/pop-low-hanging-fruit.js b/probe/pop-low-hanging-fruit.js new file mode 100644 index 0000000..e13a045 --- /dev/null +++ b/probe/pop-low-hanging-fruit.js @@ -0,0 +1,24 @@ +const str = "๐Ÿ˜€".repeat(10) + +function fold_graphemes(str, state, fun) { + let arr + while(null !== (arr = pop_grapheme(str))) { + state = fun(arr[0], state) + str = arr[1] + } + return state +} + +const segmenter = new Intl.Segmenter(); +function pop_grapheme(str) { + if (str === "") return null; + const grapheme = segmenter.segment(str)[Symbol.iterator]().next().value.segment; + return [grapheme, str.slice(grapheme.length)] +} + + +let sum = 0 +for(let i = 0; i < 100000; ++i) { + sum += fold_graphemes(str, 0, (a, b) => b + a.length) +} +console.log(sum) diff --git a/probe/pop-naive.js b/probe/pop-naive.js new file mode 100644 index 0000000..32b8a0e --- /dev/null +++ b/probe/pop-naive.js @@ -0,0 +1,24 @@ +const str = "๐Ÿ˜€".repeat(10) + +function fold_graphemes(str, state, fun) { + let arr + while(null !== (arr = pop_grapheme(str))) { + state = fun(arr[0], state) + str = arr[1] + } + return state +} + +function pop_grapheme(str) { + if (str === "") return null; + const segmenter = new Intl.Segmenter(); + const grapheme = segmenter.segment(str)[Symbol.iterator]().next().value.segment; + return [grapheme, str.slice(grapheme.length)] +} + + +let sum = 0 +for(let i = 0; i < 100000; ++i) { + sum += fold_graphemes(str, 0, (a, b) => b + a.length) +} +console.log(sum) diff --git a/probe/pop-rust.mjs b/probe/pop-rust.mjs new file mode 100644 index 0000000..2c15a0d --- /dev/null +++ b/probe/pop-rust.mjs @@ -0,0 +1,16 @@ +import { graphemeSegments } from 'unicode-segmenter/grapheme'; + +const str = "๐Ÿ˜€".repeat(100) + +function fold_graphemes(str, state, fun) { + for(const { segment: grapheme } of graphemeSegments(str)) { + state = fun(grapheme, state) + } + return state +} + +let sum = 0 +for(let i = 0; i < 100000; ++i) { + sum += fold_graphemes(str, 0, (a, b) => b + a.length) +} +console.log(sum)