diff options
author | inoas <mail@inoas.com> | 2023-06-22 15:52:43 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-22 16:52:43 +0100 |
commit | 6a097950fb48ece2a825aee33d043624967e8b76 (patch) | |
tree | b8bf07bc4e3febf54a7093c7b4db4c4ced3675b5 | |
parent | f4e41c423378175a61dd2c081e7320f41da4a235 (diff) | |
download | gleam_stdlib-6a097950fb48ece2a825aee33d043624967e8b76.tar.gz gleam_stdlib-6a097950fb48ece2a825aee33d043624967e8b76.zip |
improve JS string.join speed (#468)
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | gleam.toml | 4 | ||||
-rw-r--r-- | src/gleam/string.gleam | 21 | ||||
-rw-r--r-- | src/gleam/string_builder.gleam | 4 | ||||
-rw-r--r-- | src/gleam_stdlib.mjs | 54 |
5 files changed, 55 insertions, 29 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d74a39..fe10b24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## v0.29.2 - 2023-06-21 +- improve `string.join` and `string.concat` performance on JavaScript target. - The `result` module gains the `try_recover` function. - The `string` module gains the `byte_size` function. @@ -9,10 +9,6 @@ links = [ { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, ] -[dependencies] - -[dev-dependencies] - [javascript.deno] allow_read = [ "./", diff --git a/src/gleam/string.gleam b/src/gleam/string.gleam index b20e726..2e6f28d 100644 --- a/src/gleam/string.gleam +++ b/src/gleam/string.gleam @@ -562,9 +562,20 @@ pub fn repeat(string: String, times times: Int) -> String { /// ``` /// pub fn join(strings: List(String), with separator: String) -> String { - strings - |> list.intersperse(with: separator) - |> concat + do_join(strings, separator) +} + +if erlang { + fn do_join(strings: List(String), separator: String) -> String { + strings + |> list.intersperse(with: separator) + |> concat + } +} + +if javascript { + external fn do_join(strings: List(String), string: String) -> String = + "../gleam_stdlib.mjs" "join" } /// Pads a `String` on the left until it has at least given number of graphemes. @@ -717,8 +728,8 @@ if javascript { "../gleam_stdlib.mjs" "trim_right" } -/// Splits a non-empty `String` into its head and tail. This lets you -/// pattern match on `String`s exactly as you would with lists. +/// Splits a non-empty `String` into its first element (head) and rest (tail). +/// This lets you pattern match on `String`s exactly as you would with lists. /// /// ## Examples /// diff --git a/src/gleam/string_builder.gleam b/src/gleam/string_builder.gleam index 6137910..bb88455 100644 --- a/src/gleam/string_builder.gleam +++ b/src/gleam/string_builder.gleam @@ -89,7 +89,7 @@ if erlang { if javascript { external fn do_from_strings(List(String)) -> StringBuilder = - "../gleam_stdlib.mjs" "join" + "../gleam_stdlib.mjs" "concat" } /// Joins a list of builders into a single builder. @@ -107,7 +107,7 @@ if erlang { if javascript { external fn do_concat(List(StringBuilder)) -> StringBuilder = - "../gleam_stdlib.mjs" "join" + "../gleam_stdlib.mjs" "concat" } /// Converts a string into a builder. diff --git a/src/gleam_stdlib.mjs b/src/gleam_stdlib.mjs index 4fd06d9..6af9aff 100644 --- a/src/gleam_stdlib.mjs +++ b/src/gleam_stdlib.mjs @@ -196,8 +196,26 @@ export function split(xs, pattern) { return List.fromArray(xs.split(pattern)); } -export function join(xs) { - return xs.toArray().join(""); +export function join(xs, separator) { + let result = ""; + let i = 0; + for (const x of xs) { + if (i == 0) { + result = x + } else { + result = result + separator + x; + } + i++; + } + return result; +} + +export function concat(xs) { + let result = ""; + for (const x of xs) { + result = result + x; + } + return result; } export function length(data) { @@ -497,14 +515,14 @@ function uint6ToB64(nUint6) { return nUint6 < 26 ? nUint6 + 65 : nUint6 < 52 - ? nUint6 + 71 - : nUint6 < 62 - ? nUint6 - 4 - : nUint6 === 62 - ? 43 - : nUint6 === 63 - ? 47 - : 65; + ? nUint6 + 71 + : nUint6 < 62 + ? nUint6 - 4 + : nUint6 === 62 + ? 43 + : nUint6 === 63 + ? 47 + : 65; } // From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 @@ -512,14 +530,14 @@ function b64ToUint6(nChr) { return nChr > 64 && nChr < 91 ? nChr - 65 : nChr > 96 && nChr < 123 - ? nChr - 71 - : nChr > 47 && nChr < 58 - ? nChr + 4 - : nChr === 43 - ? 62 - : nChr === 47 - ? 63 - : 0; + ? nChr - 71 + : nChr > 47 && nChr < 58 + ? nChr + 4 + : nChr === 43 + ? 62 + : nChr === 47 + ? 63 + : 0; } // From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 |