@@ -33,6 +33,7 @@ https://github.com/xpTURN/Polyfill.git?path=src/Polyfill/Assets/Polyfill
3333```
3434
35351 . ⚙️ Run Edit > Polyfill > Player Settings > ` Apply Additional Compiler Arguments -langversion (All Installed Platforms) `
36+
3637</details >
3738
3839### ZString Installation
@@ -51,6 +52,7 @@ https://github.com/xpTURN/Polyfill.git?path=src/Polyfill/Assets/Polyfill
5152``` text
5253https://github.com/Cysharp/ZString.git?path=src/ZString.Unity/Assets/Scripts/ZString
5354```
55+
5456</details >
5557
5658## xpTURN.XString – Installation
@@ -89,7 +91,6 @@ XString.Format("{0}-{1}-{2}-{3}", "A","B","C","D");
8991
9092### Other APIs
9193
92-
9394| Method | Description |
9495| --------------------------------------------- | ------------------------------------------------------------------- |
9596| ` XString.CreateStringBuilder() ` | Create Utf16ValueStringBuilder (ZString wrapper) |
@@ -98,7 +99,6 @@ XString.Format("{0}-{1}-{2}-{3}", "A","B","C","D");
9899| ` XString.Join(separator, values) ` | Join sequence with separator (ZString wrapper) |
99100| ` XString.Concat(values) ` | Concatenate arguments in order (ZString wrapper) |
100101
101-
102102## Namespace
103103
104104- Runtime: ` xpTURN.Text `
@@ -113,6 +113,7 @@ XString.Format("{0}-{1}-{2}-{3}", "A","B","C","D");
113113``` csharp
114114_ = XString .Format ($" User: {Label } | Score: {Score : N2 } | At: {At : yyyy - MM - dd HH : mm } | Rate: {Rate : P1 }" );
115115```
116+
116117</details >
117118
118119<details >
@@ -121,6 +122,7 @@ _ = XString.Format($"User: {Label} | Score: {Score:N2} | At: {At:yyyy-MM-dd HH:m
121122``` csharp
122123_ = ZString .Format (" User: {0} | Score: {1:N2} | At: {2:yyyy-MM-dd HH:mm} | Rate: {3:P1}" , Label , Score , At , Rate );
123124```
125+
124126</details >
125127
126128<details >
@@ -129,6 +131,7 @@ _ = ZString.Format("User: {0} | Score: {1:N2} | At: {2:yyyy-MM-dd HH:mm} | Rate:
129131``` csharp
130132_ = $" User: {Label } | Score: {Score : N2 } | At: {At : yyyy - MM - dd HH : mm } | Rate: {Rate : P1 }" ;
131133```
134+
132135</details >
133136
134137<details >
@@ -137,6 +140,7 @@ _ = $"User: {Label} | Score: {Score:N2} | At: {At:yyyy-MM-dd HH:mm} | Rate: {Rat
137140``` csharp
138141_ = string .Format (" User: {0} | Score: {1:N2} | At: {2:yyyy-MM-dd HH:mm} | Rate: {3:P1}" , Label , Score , At , Rate );
139142```
143+
140144</details >
141145
142146<details >
@@ -154,6 +158,7 @@ sb.Append(" | Rate: ");
154158sb .AppendFormat (" {0:P1}" , Rate );
155159_ = sb .ToString ();
156160```
161+
157162</details >
158163
159164<details >
@@ -171,6 +176,7 @@ sb.Append(" | Rate: ");
171176sb .AppendFormat (" {0:P1}" , Rate );
172177_ = sb .ToString ();
173178```
179+
174180</details >
175181
176182<details >
@@ -188,24 +194,23 @@ sb.Append(" | Rate: ");
188194sb .AppendFormat (" {0:P1}" , Rate );
189195_ = sb .ToString ();
190196```
197+
191198</details >
192199
193200### Benchmark results
194201
195202#### GC (Time.GC) — lower is better
196203
197-
198204| Benchmark | GC Sum | Note |
199205| ---------------------------- | ------- | ---- |
200206| Utf16ValueStringBuilder | 80 | 👍 |
201207| XString (interpolated) | 80 | 👍 |
202208| ZString (format) | 80 | 👍 |
203- | StringBuilder (capacity: 128) | 140–180 | |
209+ | StringBuilder (128) | 140–180 | |
204210| String (format) | 200 | |
205211| String (interpolated) | 200 | |
206212| StringBuilder | 140–340 | |
207213
208-
209214- Utf16ValueStringBuilder, XString, and ZString all show similar GC pressure. Only the final ` new string() ` for the return value is allocated.
210215- For StringBuilder, setting capacity in advance helps. Each ` AppendFormat ` still creates temporary strings.
211216- When a single StringBuilder instance is reused across iterations (Clear then reuse), GC Sum drops to around 140.
@@ -214,18 +219,16 @@ _ = sb.ToString();
214219
215220#### Time (ms) — lower is better
216221
217-
218222| Benchmark | Min | Median | Max | Avg | StdDev |
219223| -------------------------- | ------ | ------ | ------ | ------ | ------ |
220- | Utf16ValueStringBuilder | 171.12 | 172.75 | 178.69 | 173.26 | 1.84 |
221- | ZString (format) | 171.42 | 173.18 | 178.45 | 173.95 | 2.16 |
222224| StringBuilder (shared) | 166.43 | 167.77 | 173.96 | 168.67 | 2.11 |
223225| StringBuilder(128, shared) | 169.06 | 170.86 | 174.62 | 171.40 | 1.60 |
226+ | Utf16ValueStringBuilder | 171.12 | 172.75 | 178.69 | 173.26 | 1.84 |
227+ | ZString (format) | 171.42 | 173.18 | 178.45 | 173.95 | 2.16 |
224228| XString (interpolated) | 182.89 | 184.19 | 188.63 | 184.57 | 1.60 |
225229| String (format) | 191.48 | 193.78 | 197.95 | 194.30 | 1.62 |
226230| String (interpolated) | 193.24 | 194.32 | 200.48 | 195.13 | 1.85 |
227231
228-
229232- Order by CPU load (Avg): StringBuilder (shared), StringBuilder(128) < Utf16ValueStringBuilder, ZString < XString < String.Format, string interpolation.
230233- XString is slightly slower than ZString because it converts e.g. ` (value, "D1") ` into ` AppendFormat("{0:D1}", value) ` ; that conversion uses stackalloc, so no extra heap allocation.
231234
0 commit comments