Commit 410adde
authored
For me, the `rust_i18n::i18n!` macro created tens of thousands of
hashmaps, and allocated tens of thousands of strings. Both of which were
unnecessary. This was such a problem, that it caused stack overflows (on
Windows only). This PR makes 2 optimizations:
- Reduce how `HashMap`s are created: from one for every pair, to one for
every language. Bringing the amount of HashMaps created from 14,000 to
32
- Reduce how many `String`s are created from `&'static str` by using
`Cow<'static, str>`
**Optimization 1**: Don't create so many hashmaps. The expansion of
`i18n!` creates a `HashMap` for every translation pair. I have a lot of
translations, so for me thousands of translations were being created.
Creating `HashMap` is expensive, there's no reason to do it once for
every pair
In this PR Ive changed the expansion so only a single HashMap is created
**per language**. That brings up the count of HashMap from thousands to
a only a couple.
**Optimization 2**: Don't allocate so many strings. Every call to
`add_translations` allocates both for the key, and each individual inner
pair too. Here is the body of the `add_translations` function:
```rust
pub fn add_translations(&mut self, locale: &str, data: &HashMap<&str, &str>) {
let data = data
.iter()
.map(|(k, v)| ((*k).into(), (*v).into()))
.collect::<HashMap<_, _>>();
let trs = self.translations.entry(locale.into()).or_default();
trs.extend(data);
}
```
It's considered best practice to make your function signature clear.
Usually, it's better to require a `String` rather than `&str` if you're
just going to `.to_string()` it in the function body.
it also iterates over the entire passed `data` to clone everything, and
then creates **another** hashmap (the `collect`)
All of this was causing `stack overflow` for me on Windows. The
expansion of `i18n!` generated 14,000 HashMaps and spanned over 50,000
lines. With this PR, that's not an issue anymore.
`add_translations` was changed to this:
```rust
pub fn add_translations(
&mut self,
locale: Cow<'static, str>,
data: HashMap<Cow<'static, str>, Cow<'static, str>>,
) {
let trs = self.translations.entry(locale.into()).or_default();
trs.extend(data);
}
```
Most inputs to it are static strings. There's no need to turn them into
a `String`, so they are passed as `Cow<'static, str>`.
I also added an `impl IntoIterator for SimpleBackend`.
The example expansion is located at `examples/app-egui/src/main.rs`
# Old expansion
```rust
static _RUST_I18N_BACKEND: std::sync::LazyLock<Box<dyn rust_i18n::Backend>> =
std::sync::LazyLock::new(|| {
let mut backend = rust_i18n::SimpleBackend::new();
backend.add_translations(
"en",
&std::collections::HashMap::from([("Arthur", "Arthur")]),
);
backend.add_translations("en", &std::collections::HashMap::from([("age", "age")]));
```
Note that then every of the `&'static str` you see will be
`.to_string()`d in the function call
# New expansion
This expansion both has way less overhead, and won't cause any stack
overflows
```rust
static _RUST_I18N_BACKEND: std::sync::LazyLock<Box<dyn rust_i18n::Backend>> = std::sync::LazyLock::new(||
{
let mut backend = rust_i18n::SimpleBackend::new();
backend
.add_translations(
::std::borrow::Cow::Borrowed("en"),
{
let map = std::collections::HashMap::with_capacity(278usize);
map.insert(
::std::borrow::Cow::Borrowed("Arthur", "Arthur"),
::std::borrow::Cow::Borrowed("age", "age"),
);
```
1 parent 94a91a7 commit 410adde
2 files changed
Lines changed: 82 additions & 54 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
271 | 271 | | |
272 | 272 | | |
273 | 273 | | |
274 | | - | |
275 | | - | |
276 | | - | |
277 | | - | |
278 | | - | |
279 | | - | |
280 | | - | |
281 | | - | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
282 | 289 | | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
283 | 297 | | |
284 | 298 | | |
285 | 299 | | |
| |||
325 | 339 | | |
326 | 340 | | |
327 | 341 | | |
328 | | - | |
329 | | - | |
| 342 | + | |
330 | 343 | | |
331 | 344 | | |
332 | 345 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
71 | | - | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
72 | 94 | | |
73 | 95 | | |
74 | 96 | | |
| |||
85 | 107 | | |
86 | 108 | | |
87 | 109 | | |
88 | | - | |
89 | | - | |
90 | | - | |
91 | | - | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
92 | 114 | | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
99 | 120 | | |
100 | 121 | | |
101 | 122 | | |
102 | 123 | | |
103 | 124 | | |
104 | 125 | | |
105 | 126 | | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
| 127 | + | |
111 | 128 | | |
112 | 129 | | |
113 | 130 | | |
114 | 131 | | |
115 | 132 | | |
116 | 133 | | |
117 | | - | |
| 134 | + | |
118 | 135 | | |
119 | 136 | | |
120 | 137 | | |
121 | 138 | | |
122 | 139 | | |
123 | 140 | | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | | - | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
129 | 144 | | |
130 | 145 | | |
131 | 146 | | |
| |||
148 | 163 | | |
149 | 164 | | |
150 | 165 | | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | | - | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
155 | 170 | | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
160 | 175 | | |
161 | 176 | | |
162 | 177 | | |
| |||
172 | 187 | | |
173 | 188 | | |
174 | 189 | | |
175 | | - | |
176 | | - | |
177 | | - | |
178 | | - | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
179 | 194 | | |
180 | | - | |
181 | | - | |
182 | | - | |
183 | | - | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
184 | 199 | | |
185 | 200 | | |
186 | | - | |
187 | | - | |
188 | | - | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
189 | 204 | | |
190 | | - | |
191 | | - | |
192 | | - | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
193 | 208 | | |
194 | 209 | | |
195 | 210 | | |
| |||
0 commit comments