smol-toml 1.7.2 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,39 +8,20 @@
8
8
  [![Weekly downloads](https://img.shields.io/npm/dw/smol-toml?style=flat-square)](https://npmx.dev/smol-toml)
9
9
  [![Monthly downloads](https://img.shields.io/npm/dm/smol-toml?style=flat-square)](https://npmx.dev/smol-toml)
10
10
 
11
- A small, fast, and correct TOML parser and serializer. smol-toml is fully(ish) spec-compliant with TOML v1.1.0.
11
+ A small, fast, and correct TOML parser and serializer. smol-toml is fully spec-compliant with TOML v1.1.0, passing
12
+ all[^toml-test-asterisk] tests from the [official `toml-test` suite](https://github.com/toml-lang/toml-test).
12
13
 
13
- Why yet another TOML parser? Well, the ecosystem of TOML parsers in JavaScript is quite underwhelming, most likely due
14
- to a lack of interest. With most parsers being outdated, unmaintained, non-compliant, or a combination of these, a new
15
- parser didn't feel too out of place.
14
+ [^toml-test-asterisk]: By default, certain invalid datetimes (e.g. `2020-02-30`) are gracefully accepted. Due to
15
+ JavaScript's lax handling of Unicode, some invalid byte sequences are accepted. Requires using the `integersAsBigInt`
16
+ option for full type preservation. Use the `run-toml-test.bash` script to run the tests.
16
17
 
17
- *[insert xkcd 927]*
18
-
19
- Nowadays, smol-toml is the most downloaded TOML parser on npm thanks to its quality. From frameworks to tooling, it
20
- has been battle-tested and is actively used in production systems.
21
-
22
- smol-toml passes most of the tests from the [`toml-test` suite](https://github.com/toml-lang/toml-test); use the
23
- `run-toml-test.bash` script to run the tests. Due to the nature of JavaScript and the limits of the language,
24
- it doesn't pass certain tests, namely:
25
- - Invalid UTF-8 strings (and comments) are not rejected
26
- - Certain invalid dates are not rejected
27
- - For instance, `2023-02-30` would be accepted and parsed as `2023-03-02`. While additional checks could be performed
28
- to reject these, they've not been added for performance reasons.
29
-
30
- Please also note that by default, the behavior regarding integers doesn't preserve type information, nor does it allow
31
- deserializing integers larger than 53 bits. See [Integers](#integers).
32
-
33
- You can see a list of all tests smol-toml fails (and the reason why it fails these) in the list of skipped tests in
34
- `run-toml-test.bash`. Note that some failures are *not* specification violations per-se. For instance, the TOML spec
35
- does not require 64-bit integer range support or sub-millisecond time precision, but are included in the `toml-test`
36
- suite. See https://github.com/toml-lang/toml-test/issues/154 and https://github.com/toml-lang/toml-test/issues/155
37
-
38
- ## Installation
39
- ```
40
- [pnpm | yarn | npm] i smol-toml
41
- ```
18
+ > [!IMPORTANT]
19
+ > - By default, the behaviour regarding integers doesn't preserve type information, nor does it allow deserializing
20
+ > integers larger than 53 bits. See [Integers](#integers).
21
+ > - The library currently uses the legacy `Date` object by default. See [Date, Time, and Datetime](#date-time-and-datetime).
42
22
 
43
23
  ## Usage
24
+
44
25
  ```js
45
26
  import { parse, stringify } from 'smol-toml'
46
27
 
@@ -60,25 +41,77 @@ TOML.stringify({ ... })
60
41
  ```
61
42
 
62
43
  A few notes on the `stringify` function:
63
- - `undefined` and `null` values on objects are ignored (does not produce a key/value).
44
+ - `undefined` and `null` values on objects are ignored (they do not produce a key/value).
64
45
  - `undefined` and `null` values in arrays are **rejected**.
65
46
  - Functions, classes and symbols are **rejected**.
66
- - By default, floats will be serialized as integers if they don't have a decimal part. See [Integers](#integers)
67
- - `stringify(parse('a = 1.0')) === 'a = 1'`
68
- - JS `Date` will be serialized as Offset Date Time
69
- - Use the [`TomlDate` object](#dates) for representing other types.
47
+ - By default, floats will be serialized as integers if they don't have a decimal part.
48
+ - i.e. `stringify(parse('a = 1.0'))` will produce `a = 1`, despite the source value being a float.
49
+ - See [Integers](#integers) for end-to-end type preservation using `BigInt`.
50
+ - JS `Date` will be serialized as an Offset Date-Time in UTC.
51
+ - Use the [Temporal API] for representing other types (or alternatively the legacy [`TomlDate` object](#tomldate-object)).
52
+
53
+ ### Options
54
+
55
+ Both `parse` and `stringify` accept an options object as 2nd argument.
56
+
57
+ #### Parse options
58
+
59
+ | Option | Type | Default | Description | Introduced in |
60
+ |----------------------|-------------------------------|----------|-----------------------------------------------------------------------------------------------------------------|---------------|
61
+ | `integersAsBigInt` | `boolean \| 'asNeeded'` | `false` | Parse integers as `BigInt`. See [Integers](#integers). | 1.4.0 |
62
+ | `useLegacyDate` | `boolean` | `true` | Use the legacy `TomlDate` instead of the Temporal API. See [Date, Time, and Datetime](#date-time-and-datetime). | 1.9.0 |
63
+ | `unsafeKeyBehaviour` | `'keep' \| 'drop' \| 'throw'` | `'keep'` | Reject potentially dangerous keys such as `__proto__` or `constructor`. See [Key safety](#key-safety). | 1.9.0 |
64
+
65
+ ##### Key safety
66
+
67
+ Internally, `smol-toml` is protected against prototype pollution and will correctly assign a plain property named e.g.
68
+ `__proto__` on the object, similar to what JavaScript-native `JSON.parse` does.
69
+
70
+ However, careless use of the object returned by the parser in your application code may lead to prototype pollution.
71
+ This is for instance the case in this example taken from Fastify's `secure-json-parse` helper which exists to address
72
+ this caveat.
73
+
74
+ ```js
75
+ import { parse } from 'smol-toml'
76
+
77
+ const a = parse('__proto__.b = 5')
78
+ console.log(a.b) // ~> undefined
79
+
80
+ const b = Object.assign({}, a)
81
+ console.log(b.b) // ~> 5
82
+ ```
83
+
84
+ Similarly to `secure-json-parse`, the library offers 3 modes to deal with these keys:
85
+ - `keep` (default): preserve potentially unsafe properties and return the object as-is.
86
+ - `drop`: silently drop potentially unsafe properties, returning the object as if the properties were not there.
87
+ - `throw`: reject documents with potentially unsafe properties and throw a `TomlError`.
88
+
89
+ #### Stringify options
90
+
91
+ | Option | Type | Default | Description | Introduced in |
92
+ |------------------|-----------|------------|--------------------------------------------------------------------------------------------------------------------------------|---------------|
93
+ | `numbersAsFloat` | `boolean` | `false` | Always render plain numbers as floating point values. See [Type preservation](#type-preservation). | 1.4.0 |
94
+ | `strictTemporal` | `boolean` | `false` | Reject Temporal values with an IANA timezone or a calendar. See [IANA timezones and calendars](#iana-timezones-and-calendars). | 1.9.0 |
95
+
96
+ ## Dealing with values
70
97
 
71
98
  ### Integers
72
- When parsing, both integers and floats are read as plain JavaScript numbers, which essentially are floats. This means
73
- loss of type information, and makes it impossible to safely represent integers beyond 53 bits.
99
+
100
+ When parsing, both integers and floats are parsed as plain JavaScript numbers by default, which are double-precision
101
+ floating point numbers. That means that the library does not preserve type information between e.g. `1.0` and `1`, and
102
+ that it is not able to parse integers beyond 53 bits.
103
+
104
+ While this is sufficient for the vast majority of use-cases, if support of larger integers is needed, it is possible
105
+ to [enable BigInt support](#enabling-bigint).
74
106
 
75
107
  When serializing, numbers without a decimal part are serialized as integers (except if they're outside of the safe
76
- range; i.e. they cannot be represented as a signed 53-bit integer). This allows in most cases to preserve
77
- whether a number is an integer or not, but fails to preserve type information for numbers like `1.0`.
108
+ range; i.e. they cannot be represented as a signed 53-bit integer). This is generally a good enough heuristic for most
109
+ usages, but it is possible to leverage BigInts for [full type preservation](#type-preservation).
110
+
111
+ #### Enabling BigInt
78
112
 
79
- #### Enabling BigInt support and type preservation
80
113
  To parse integers beyond 53 bits, it's possible to tell the parser to return all integers as BigInt. This will
81
- therefore preserve the type information at the cost of using a slightly more expensive container.
114
+ therefore preserve the type information at the cost of using a more expensive container (approx. 5% slowdown).
82
115
 
83
116
  ```js
84
117
  import { parse } from 'smol-toml'
@@ -87,9 +120,11 @@ const doc = '...'
87
120
  const parsed = parse(doc, { integersAsBigInt: true })
88
121
  ```
89
122
 
90
- If you want to keep numbers for integers that can safely be represented as a JavaScript number, you can pass
123
+ If you want to only use BigInt for numbers that cannot safely be represented as plain JavaScript numbers, you can pass
91
124
  `"asNeeded"` instead.
92
125
 
126
+ ##### Type preservation
127
+
93
128
  To get end-to-end type preservation, you can tell the serializer to always treat numbers as floating point numbers.
94
129
  Then, only BigInts will be serialized as integers and numbers without a decimal part will still be serialized as float.
95
130
 
@@ -100,9 +135,77 @@ const obj = { ... }
100
135
  const toml = stringify(obj, { numbersAsFloat: true })
101
136
  ```
102
137
 
103
- ### Dates
104
- `smol-toml` uses an extended `Date` object to represent all types of TOML Dates. In the future, `smol-toml` will use
105
- objects from the Temporal proposal, but for now we're stuck with the legacy Date object.
138
+ ### Date, Time, and Datetime
139
+
140
+ `smol-toml` can emit time-related types in 2 ways: the modern [Temporal API], or the legacy (_but currently default_)
141
+ `Date` object, using a custom [`TomlDate` object](#tomldate-object).
142
+
143
+ > [!NOTE]
144
+ > While `TomlDate` is 2-3x faster than Temporal in microbenchmarks, the performance difference in practice on parse
145
+ > time is insignificant (or even slower[^temporal-slow-or-fast]) for `smol-toml`. See the [benchmarks](#benchmarks).
146
+ >
147
+ > `TomlDate` is limited to millisecond precision and has a more lax behaviour. It gracefully accepts certain invalid
148
+ > inputs, such as "the 30th of February", converting it to the 2nd (or 1st) of March. The Temporal implementation is
149
+ > stricter and properly rejects these invalid dates.
150
+ >
151
+ > The next major version of the library will use Temporal by default.
152
+
153
+ [^temporal-slow-or-fast]: The `Temporal` implementation dispatches more instructions to the CPU; however, it is much
154
+ more friendly to the branch predictor. At the microarchitecture level, this allows the CPU
155
+ to reach a higher number of _instructions per clock_, which results in a net positive
156
+ performance impact. The CPU has to do _more_, but it can do it _faster_.
157
+
158
+ The different TOML types and Temporal types are mapped as described below.
159
+
160
+ #### TOML type to Temporal mapping
161
+
162
+ | TOML type | Temporal type |
163
+ |----------------------------------------------------------------|----------------------------|
164
+ | [Offset Date-Time](https://toml.io/en/v1.1.0#offset-date-time) | [`Temporal.ZonedDateTime`] |
165
+ | [Local Date-Time](https://toml.io/en/v1.1.0#local-date-time) | [`Temporal.PlainDateTime`] |
166
+ | [Local Date](https://toml.io/en/v1.1.0#local-date) | [`Temporal.PlainDate`] |
167
+ | [Local Time](https://toml.io/en/v1.1.0#local-time) | [`Temporal.PlainTime`] |
168
+
169
+ #### Temporal to TOML type mapping
170
+
171
+ | Temporal type | TOML type | Notes |
172
+ |-----------------------------|----------------------------------------------------------------|----------------------------------------------------------------------------------|
173
+ | [`Temporal.Duration`] | **Unsupported** (throws) | There is an ongoing [feature request][toml-lang/toml#514] and an [active proposal][toml-lang/toml#1105]. Note that the current draft does not allow multi-part values (e.g. `1min 20sec`), making it likely that `Duration` will not always be convertible to a TOML value. |
174
+ | [`Temporal.Instant`] | [Offset Date-Time](https://toml.io/en/v1.1.0#offset-date-time) | Always in UTC. |
175
+ | [`Temporal.PlainDate`] | [Local Date](https://toml.io/en/v1.1.0#local-date) | Calendar info lost, [see below](#iana-timezones-and-calendars). |
176
+ | [`Temporal.PlainDateTime`] | [Local Date-Time](https://toml.io/en/v1.1.0#local-date-time) | Calendar info lost, [see below](#iana-timezones-and-calendars). |
177
+ | [`Temporal.PlainMonthDay`] | **Unsupported** (throws) | |
178
+ | [`Temporal.PlainTime`] | [Local Time](https://toml.io/en/v1.1.0#local-time) | |
179
+ | [`Temporal.PlainYearMonth`] | **Unsupported** (throws) | |
180
+ | [`Temporal.ZonedDateTime`] | [Offset Date-Time](https://toml.io/en/v1.1.0#offset-date-time) | IANA timezone and calendar info lost, [see below](#iana-timezones-and-calendars). |
181
+
182
+ ##### IANA timezones and calendars
183
+
184
+ `ZonedDateTime` objects may have 2 different types of timezone identifier attached to them: either an offset such as
185
+ `+02:00`, or an [IANA Time Zone Identifier](https://www.iana.org/time-zones) such as `Europe/Paris`. The latter carries
186
+ information about the currently observed offset in that region, daylight savings policies, and other timekeeping quirks
187
+ such as leap seconds. It is a much more precise information than the offset alone. Additionally, `ZonedDateTime` allows
188
+ keeping track of a specific calendar to use, such as for example the *Japanese imperial era*.
189
+
190
+ TOML can only represent offsets, not precise timezones nor a calendar[^tz-request]. As such, when serializing a
191
+ `ZonedDateTime`, this information is **lost** and only the offset is preserved; effectively treating the `ZonedDateTime`
192
+ as if it were an `Instant`. To prevent silent loss of timezone information, the `strictTemporal` option can be
193
+ enabled to throw an error instead. Timezones that aren't simple offsets, or objects using a calendar that isn't
194
+ the default ISO 8601 will be rejected.
195
+
196
+ [^tz-request]: There was a request to support the [RFC 9557] syntax, but it has been rejected. See [toml-lang/toml#1034].
197
+
198
+ #### TomlDate object
199
+ > [!NOTE]
200
+ > This object is not formally deprecated yet, but it is a legacy API. It will be deprecated in v2 and removed in v3.
201
+
202
+ The object directly inherits the JavaScript `Date` object, with a handful of extra APIs for distinguishing between
203
+ different types of time components.
204
+
205
+ `TomlDate` preserves the offset, whereas the native `Date` object usually normalises everything to UTC.
206
+
207
+ > [!CAUTION]
208
+ > Unlike the [Temporal API] which supports nanosecond precision, `Date` is limited to millisecond precision.
106
209
 
107
210
  ```js
108
211
  import { TomlDate } from 'smol-toml'
@@ -143,260 +246,360 @@ const localTime = TomlDate.wrapAsLocalTime(jsDate)
143
246
  ```
144
247
 
145
248
  ## Performance
146
- The benchmark is ran using [mitata](https://github.com/evanwashere/mitata).
147
-
148
- Parsers and serializers are tested in 2 scenarios: using the example from TOML's homepage and specification, and
149
- using a ~5MB randomly generated[^generator] file.
150
-
151
- [^generator]: The TOML generator used can be found [here](https://gist.github.com/cyyynthia/e77c744cb6494dabe37d0182506526b9)
152
-
153
- While `fast-toml` is included as it's a challenging candidate, it takes a lot of shortcuts that makes it very fast,
154
- but at the expense of correctness (it has significant defects and does not pass the TOML test suite). `smol-toml` is
155
- almost as fast, without sacrificing correctness. 😎
156
-
157
- | **Parse** | smol-toml@1.7.2 | @iarna/toml@3.0.0 | @ltd/j-toml@1.38.0 | fast-toml@0.5.4 | @std/toml@1.0.11 | toml@5.0.0 | js-toml@2.0.1 | @decimalturn/toml-patch@3.0.2 |
158
- |----------------|--------------------|-------------------|--------------------|-------------------|------------------|----------------|----------------|-------------------------------|
159
- | Spec example | **4.16 µs/iter** | 12.13 µs/iter | 30.44 µs/iter | 5.01 µs/iter | 22.34 µs/iter | 32.28 µs/iter | 24.71 µs/iter | 17.07 µs/iter |
160
- | ~5MB test file | *113.76 ms/iter* | *DNF* | 189.89 ms/iter | **92.24 ms/iter** | 419.95 ms/iter | 549.86 ms/iter | 336.03 ms/iter | 186.32 ms/iter |
161
-
162
- | **Stringify** | smol-toml@1.7.2 | @iarna/toml@3.0.0 | @ltd/j-toml@1.38.0 | fast-toml@0.5.4 | @std/toml@1.0.11 | toml@5.0.0 | js-toml@2.0.1 | @decimalturn/toml-patch@3.0.2 |
163
- |----------------|--------------------|-------------------|--------------------|-----------------|------------------|----------------|----------------|-------------------------------|
164
- | Spec example | **2.29 µs/iter** | 8.58 µs/iter | 89.59 µs/iter | N/A | 3.96 µs/iter | N/A | 3.69 µs/iter | N/A[^toml-patch-note] |
165
- | ~5MB test file | **45.33 ms/iter** | 130.01 ms/iter | 928.19 ms/iter | N/A | 68.58 ms/iter | N/A | 110.26 ms/iter | N/A[^toml-patch-note] |
166
-
167
- [^toml-patch-note]: Stringify performance is not included here, as the library is not meant to be fast, but rather
168
- capable of doing precise non-destructive edits that preserve the entire document's shape and format. Putting it here
169
- wouldn't be fair.
249
+ The benchmark is ran using [mitata](https://github.com/evanwashere/mitata). See the sources in `bench`.
250
+
251
+ > [!NOTE]
252
+ > - The output of `smol-toml` with Temporal *disabled* is used as the starting value for stringify benchmarks.
253
+ > - The TOML generator used to create the 5MB test file can be found [here](https://gist.github.com/cyyynthia/e77c744cb6494dabe37d0182506526b9).
254
+
255
+ ### Results
256
+ - [Parse, spec example](#parse-spec-example)
257
+ - [Parse, 5MB randomly generated file](#parse-5mb-randomly-generated)
258
+ - [Stringify, spec example](#parse-spec-example)
259
+ - [Stringify, 5MB randomly generated file](#parse-5mb-randomly-generated)
260
+
261
+ #### Parse, spec example
262
+
263
+ | | Library | Performance | Slowdown | Notes |
264
+ |:--:|------------------------------------------|---------------|----------|-------|
265
+ | 🥇 | smol-toml@1.9.0 (Date) | 2.98 µs/iter | 1x | |
266
+ | 🥈 | smol-toml@1.9.0 (Temporal) | 3.14 µs/iter | 1.06x | |
267
+ | 🥉 | fast-toml@0.5.4 | 5.13 µs/iter | 1.72x | Unmaintained. No handling of special floats. Bad handling of some unicode escapes. Parses `nan` as `false`. |
268
+ | 4 | @iarna/toml@3.0.0 | 12.66 µs/iter | 4.25x | Unmaintained. Has defects in datetime parsing. Uses `eval`. |
269
+ | 5 | @decimalturn/toml-patch@3.1.2 (Date) | 19.60 µs/iter | 6.58x | Special-purpose: designed for non-destructive document edition. |
270
+ | 6 | @decimalturn/toml-patch@3.1.2 (Temporal) | 20.98 µs/iter | 7.04x | Special-purpose: designed for non-destructive document edition. |
271
+ | 7 | @std/toml@1.0.11 | 22.81 µs/iter | 7.66x | |
272
+ | 8 | js-toml@2.0.1 | 23.00 µs/iter | 7.72x | |
273
+ | 9 | @ltd/j-toml@1.38.0 | 31.25 µs/iter | 10.49x | Unmaintained. Has defects in number parsing when disabling `bigint`. |
274
+ | 10 | toml@5.0.0 (Temporal) | 33.04 µs/iter | 11.09x | |
275
+ | 11 | toml@5.0.0 (Date/string) | 33.20 µs/iter | 11.15x | |
276
+
277
+ #### Parse, 5MB randomly generated file
278
+
279
+ | | Library | Performance | Slowdown | Notes |
280
+ |:--:|------------------------------------------|----------------|----------|-------|
281
+ | 🥇 | smol-toml@1.9.0 (Temporal) | 45.05 ms/iter | 1x | |
282
+ | 🥈 | smol-toml@1.9.0 (Date) | 47.71 ms/iter | 1.06x | |
283
+ | 🥉 | fast-toml@0.5.4 | 92.50 ms/iter | 2.05x | Unmaintained. No handling of special floats. Bad handling of some unicode escapes. Parses `nan` as `false`. |
284
+ | 4 | @ltd/j-toml@1.38.0 | 186.47 ms/iter | 4.14x | Unmaintained. Has defects in number parsing when disabling `bigint`. |
285
+ | 5 | @decimalturn/toml-patch@3.1.2 (Date) | 207.09 ms/iter | 4.6x | Special-purpose: designed for non-destructive document edition. |
286
+ | 6 | @decimalturn/toml-patch@3.1.2 (Temporal) | 219.53 ms/iter | 4.87x | Special-purpose: designed for non-destructive document edition. |
287
+ | 7 | js-toml@2.0.1 | 280.63 ms/iter | 6.23x | |
288
+ | 8 | @std/toml@1.0.11 | 428.34 ms/iter | 9.51x | |
289
+ | 9 | toml@5.0.0 (Date/string) | 557.91 ms/iter | 12.38x | |
290
+ | 10 | toml@5.0.0 (Temporal) | 587.43 ms/iter | 13.04x | |
291
+ | - | @iarna/toml@3.0.0 | **DNF** | **DNF** | Unmaintained. Has defects in datetime parsing. Uses `eval`. |
292
+
293
+ #### Stringify, spec example
294
+
295
+ | | Library | Performance | Slowdown | Notes |
296
+ |:-:|-------------------------------|---------------|----------|-------|
297
+ | 🥇 | smol-toml@1.9.0 | 2.68 µs/iter | 1x | |
298
+ | 🥈 | @std/toml@1.0.11 | 4.86 µs/iter | 1.81x | |
299
+ | 🥉 | js-toml@2.0.1 | 5.76 µs/iter | 2.15x | |
300
+ | 4 | @iarna/toml@3.0.0 | 9.71 µs/iter | 3.62x | Unmaintained. |
301
+ | 5 | @ltd/j-toml@1.38.0 | 48.15 µs/iter | 17.96x | Unmaintained. |
302
+ | 6 | @decimalturn/toml-patch@3.1.2 | 59.57 µs/iter | 22.22x | Special-purpose: designed for non-destructive document edition. |
303
+
304
+ #### Stringify, 5MB randomly generated file
305
+
306
+ | | Library | Performance | Slowdown | Notes |
307
+ |:-:|-------------------------------|----------------|----------|-------|
308
+ | 🥇 | smol-toml@1.9.0 | 43.72 ms/iter | 1x | |
309
+ | 🥈 | @std/toml@1.0.11 | 71.01 ms/iter | 1.62x | |
310
+ | 🥉 | js-toml@2.0.1 | 107.22 ms/iter | 2.45x | |
311
+ | 4 | @iarna/toml@3.0.0 | 134.59 ms/iter | 3.08x | Unmaintained. |
312
+ | 5 | @ltd/j-toml@1.38.0 | 383.10 ms/iter | 8.76x | Unmaintained. |
313
+ | 6 | @decimalturn/toml-patch@3.1.2 | 543.69 ms/iter | 12.44x | Special-purpose: designed for non-destructive document edition. |
314
+
315
+ ### Detailed benchmark data
170
316
 
171
317
  <details>
172
318
  <summary>Detailed benchmark data</summary>
173
319
 
174
320
  ```
175
321
  node --expose-gc bench/parse.bench.ts
176
- clk: ~5.52 GHz
322
+ clk: ~5.39 GHz
177
323
  cpu: AMD Ryzen 9 9950X3D 16-Core Processor
178
- runtime: node 26.5.0 (x64-linux)
324
+ runtime: node 26.10.0 (x64-linux)
179
325
 
180
- benchmark avg (min … max) p75 / p99 (min … top 1%)
181
- ------------------------------------------- -------------------------------
326
+ benchmark avg (min … max) p75 / p99 (min … top 1%)
327
+ ------------------------------------------------- -------------------------------
182
328
  • spec document
183
- ------------------------------------------- -------------------------------
184
- smol-toml 4.16 µs/iter 4.14 µs █
185
- (3.99 µs … 91.94 µs) 4.95 µs ▂█▃
186
- ( 1.41 kb … 417.70 kb) 9.63 kb ▁███▅▃▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁
187
- 4.01 ipc ( 99.54% cache) 19.70 branch misses
188
- 23.81k cycles 95.44k instructions 3.05k c-refs 14.12 c-misses
189
-
190
- @iarna/toml 12.13 µs/iter 12.04 µs █
191
- (11.59 µs … 133.43 µs) 15.94 µs █▄
192
- ( 0.00 b … 677.01 kb) 24.08 kb ▃██▄▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
193
- 3.97 ipc ( 99.63% cache) 75.32 branch misses
194
- 68.16k cycles 270.90k instructions 10.39k c-refs 38.82 c-misses
195
-
196
- @ltd/j-toml 30.44 µs/iter 29.57 µs █
197
- (28.19 µs … 1.18 ms) 44.30 µs █▅
198
- (432.00 b … 692.05 kb) 27.57 kb ▂██▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
199
- 3.42 ipc ( 99.37% cache) 284.51 branch misses
200
- 169.50k cycles 579.61k instructions 25.59k c-refs 162.02 c-misses
201
-
202
- fast-toml 5.01 µs/iter 4.98 µs ▄█
203
- (4.75 µs … 90.47 µs) 5.84 µs ██▃
204
- (336.00 b … 302.06 kb) 12.56 kb ▁▅███▆▅▃▂▂▁▁▁▁▁▁▁▁▁▁▁
205
- 4.40 ipc ( 99.53% cache) 25.73 branch misses
206
- 28.21k cycles 124.23k instructions 3.76k c-refs 17.82 c-misses
207
-
208
- deno's @std/toml 22.34 µs/iter 22.15 µs █▅
209
- (20.78 µs … 155.43 µs) 36.68 µs ██
210
- ( 1.52 kb … 547.05 kb) 64.73 kb ▂██▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
211
- 3.80 ipc ( 99.53% cache) 111.24 branch misses
212
- 124.05k cycles 471.06k instructions 21.13k c-refs 100.20 c-misses
213
-
214
- node-toml 32.28 µs/iter 31.78 µs █
215
- (30.33 µs … 221.49 µs) 53.65 µs █
216
- ( 2.00 kb … 968.27 kb) 109.52 kb ▆█▄▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
217
- 3.89 ipc ( 99.18% cache) 193.02 branch misses
218
- 178.72k cycles 695.61k instructions 29.40k c-refs 240.75 c-misses
219
-
220
- js-toml 24.71 µs/iter 23.17 µs ▅█
221
- (21.20 µs … 731.20 µs) 39.47 µs ██
222
- (744.00 b … 861.36 kb) 92.95 kb ▂██▅▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁
223
- 3.79 ipc ( 98.12% cache) 205.75 branch misses
224
- 134.81k cycles 510.43k instructions 19.00k c-refs 357.65 c-misses
225
-
226
- @decimalturn/toml-patch 17.07 µs/iter 16.85 µs █▆
227
- (15.93 µs … 224.97 µs) 23.30 µs ██
228
- (632.00 b … 635.14 kb) 55.51 kb ▂██▇▃▂▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁
229
- 3.56 ipc ( 99.37% cache) 73.96 branch misses
230
- 95.58k cycles 339.88k instructions 18.52k c-refs 116.43 c-misses
329
+ ------------------------------------------------- -------------------------------
330
+ smol-toml (Date) 2.98 µs/iter 2.93 µs █
331
+ (2.81 µs … 98.78 µs) 4.21 µs █▂
332
+ (440.00 b … 236.20 kb) 12.70 kb ▁██▃▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
333
+ 4.46 ipc ( 99.06% cache) 16.97 branch misses
334
+ 16.79k cycles 74.80k instructions 2.21k c-refs 20.71 c-misses
335
+
336
+ smol-toml (Temporal) 3.14 µs/iter 3.16 µs █
337
+ (3.10 µs … 3.20 µs) 3.20 µs ▇▇ ▂ ▅█▅▂▂
338
+ ( 4.60 kb … 4.62 kb) 4.61 kb ██▇█▇▁▁▄▄▇▄█████▄▄▇▄▄
339
+ 4.47 ipc ( 99.22% cache) 12.39 branch misses
340
+ 17.24k cycles 77.01k instructions 2.32k c-refs 18.12 c-misses
341
+
342
+ @iarna/toml 12.66 µs/iter 12.51 µs █
343
+ (12.09 µs … 104.09 µs) 16.70 µs █
344
+ (192.00 b … 454.46 kb) 24.09 kb ▄██▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
345
+ 3.87 ipc ( 99.63% cache) 84.59 branch misses
346
+ 70.08k cycles 271.21k instructions 11.96k c-refs 44.06 c-misses
347
+
348
+ @ltd/j-toml 31.25 µs/iter 30.76 µs ▄██▂
349
+ (29.69 µs … 851.32 µs) 34.20 µs ████
350
+ (760.00 b … 537.88 kb) 27.54 kb ▁▅████▇▃▂▁▁▂▁▂▁▁▁▁▁▁▁
351
+ 3.35 ipc ( 99.48% cache) 293.85 branch misses
352
+ 172.79k cycles 578.79k instructions 31.46k c-refs 165.17 c-misses
353
+
354
+ fast-toml 5.13 µs/iter 5.10 µs █
355
+ (4.96 µs … 89.84 µs) 6.09 µs ▃█
356
+ (400.00 b … 376.82 kb) 12.63 kb ▁██▅▃▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
357
+ 4.49 ipc ( 99.53% cache) 13.42 branch misses
358
+ 28.68k cycles 128.90k instructions 3.91k c-refs 18.52 c-misses
359
+
360
+ @std/toml 22.81 µs/iter 22.71 µs █
361
+ (21.45 µs … 148.45 µs) 29.40 µs █
362
+ (120.00 b … 498.46 kb) 64.90 kb ▁▄▇█▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
363
+ 3.75 ipc ( 99.54% cache) 105.52 branch misses
364
+ 125.75k cycles 471.96k instructions 24.08k c-refs 110.15 c-misses
365
+
366
+ toml (Date/string) 33.20 µs/iter 31.60 µs █
367
+ (30.38 µs … 3.01 ms) 51.14 µs █
368
+ (952.00 b … 1.56 mb) 108.82 kb ▆█▃▃▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
369
+ 3.96 ipc ( 99.06% cache) 181.78 branch misses
370
+ 177.03k cycles 700.26k instructions 30.31k c-refs 286.20 c-misses
371
+
372
+ toml (Temporal) 33.04 µs/iter 31.76 µs █
373
+ (31.47 µs … 47.08 µs) 33.37 µs █▂ ▂
374
+ ( 6.40 kb … 8.14 kb) 6.98 kb ██▁█▁▆▁▁▁▁▁▁▁▁▁▁▁▁▁▁▆
375
+ 3.94 ipc ( 99.13% cache) 176.95 branch misses
376
+ 177.43k cycles 699.67k instructions 31.56k c-refs 274.71 c-misses
377
+
378
+ js-toml 23.00 µs/iter 21.48 µs █
379
+ (20.32 µs … 2.18 ms) 32.27 µs █▆
380
+ ( 0.99 kb … 1.45 mb) 92.46 kb ▂██▃▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
381
+ 4.10 ipc ( 98.16% cache) 178.29 branch misses
382
+ 122.97k cycles 504.24k instructions 20.34k c-refs 374.28 c-misses
383
+
384
+ @decimalturn/toml-patch (Date) 19.60 µs/iter 19.09 µs █
385
+ (18.53 µs … 841.76 µs) 26.77 µs █
386
+ (608.00 b … 607.52 kb) 60.02 kb ▃█▄▂▂▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁
387
+ 3.54 ipc ( 99.33% cache) 104.70 branch misses
388
+ 107.96k cycles 382.10k instructions 23.95k c-refs 160.21 c-misses
389
+
390
+ @decimalturn/toml-patch (Temporal) 20.98 µs/iter 20.24 µs ██ █
391
+ (20.12 µs … 29.49 µs) 20.51 µs ██▅█▅ ▅ ▅ ▅
392
+ ( 2.55 kb … 4.41 kb) 2.86 kb █████▁█▁▁█▁▁▁▁▁▁▁▁▁▁█
393
+ 3.52 ipc ( 99.29% cache) 106.72 branch misses
394
+ 114.13k cycles 401.87k instructions 25.31k c-refs 179.37 c-misses
231
395
 
232
396
  summary
233
- smol-toml
234
- 1.2x faster than fast-toml
235
- 2.92x faster than @iarna/toml
236
- 4.1x faster than @decimalturn/toml-patch
237
- 5.37x faster than deno's @std/toml
238
- 5.94x faster than js-toml
239
- 7.31x faster than @ltd/j-toml
240
- 7.76x faster than node-toml
397
+ smol-toml (Date)
398
+ 1.06x faster than smol-toml (Temporal)
399
+ 1.72x faster than fast-toml
400
+ 4.25x faster than @iarna/toml
401
+ 6.58x faster than @decimalturn/toml-patch (Date)
402
+ 7.04x faster than @decimalturn/toml-patch (Temporal)
403
+ 7.66x faster than @std/toml
404
+ 7.72x faster than js-toml
405
+ 10.49x faster than @ltd/j-toml
406
+ 11.09x faster than toml (Temporal)
407
+ 11.15x faster than toml (Date/string)
241
408
 
242
409
  • 5MB document
243
- ------------------------------------------- -------------------------------
244
- smol-toml 113.76 ms/iter 115.67 ms █ █ █
245
- (106.25 ms … 121.53 ms) 118.63 ms ▅ █ ▅ █ ▅ █ ▅ ▅
246
- ( 37.31 mb … 49.50 mb) 43.97 mb █▁▁▁▁█▁▁▁█▁█▁█▁█▁█▁▁█
247
- 2.47 ipc ( 98.58% cache) 3.12M branch misses
248
- 606.38M cycles 1.50G instructions 78.32M c-refs 1.11M c-misses
249
-
250
- @iarna/toml error: Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z at row 5, col 45, pos 569:
410
+ ------------------------------------------------- -------------------------------
411
+ smol-toml (Date) 47.71 ms/iter 50.08 ms █
412
+ (44.72 ms … 50.16 ms) 50.09 ms █
413
+ ( 27.91 mb … 37.81 mb) 33.32 mb █▁█▁████▁▁▁▁▁▁▁▁▁▁▁██
414
+ 3.05 ipc ( 96.95% cache) 1.95M branch misses
415
+ 249.63M cycles 760.48M instructions 23.70M c-refs 723.86k c-misses
416
+
417
+ smol-toml (Temporal) 45.05 ms/iter 46.17 ms █
418
+ (43.04 ms … 47.19 ms) 47.06 ms ▅█ ▅▅ ▅ ▅ ▅▅▅ ▅
419
+ ( 25.17 mb … 36.61 mb) 31.28 mb ██▁██▁▁▁▁█▁▁▁█▁███▁▁█
420
+ 3.09 ipc ( 97.25% cache) 1.52M branch misses
421
+ 244.27M cycles 754.78M instructions 29.60M c-refs 813.69k c-misses
422
+
423
+ @iarna/toml error: Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z at row 5, col 45, pos 569:
251
424
  4: NfF6LuAerfn5mDPI7Cp 2qsrB4vGmJTyb5jNubOIBYYWrWlAsrw PX93S57gjb5GEhR8qOU5blDQmwfVJTA YvmJ9cE3cUZU NAJQgAbIdpZLhc4lOs4ZhMEWehhZqXCsVD1YP1vN2GEoM2WX''', 1986-05-27T18:36:13Z, -5460, "2ZAV3fYlb23hf7r7QoftVlicWE2iuwp", 4790.2253 ]
252
425
  5> SzeC4Me8T = [ 5928.9340, 1991-04-28 19:24:24, 7807, -782.4516, 0b1000011111, "YvXRZKBGle9d51sqE90t8hP" ]
253
426
  ^
254
427
  6: SLMvBirT.pmpX1D.9PivpfFBo = 2010-09-29
255
428
 
256
-
257
-
258
- @ltd/j-toml 189.89 ms/iter 197.10 ms ██ █
259
- (172.17 ms … 237.08 ms) 210.60 ms ▅ ▅██ ▅ ▅ █ ▅
260
- ( 19.71 mb … 56.03 mb) 36.30 mb █▁███▁█▁▁█▁▁▁█▁▁▁▁▁▁█
261
- 2.41 ipc ( 97.92% cache) 3.88M branch misses
262
- 1.03G cycles 2.49G instructions 143.96M c-refs 3.00M c-misses
263
-
264
- fast-toml 92.24 ms/iter 95.41 ms █ █
265
- (88.83 ms … 96.21 ms) 96.00 ms █ ▅ ▅▅█▅ ▅▅▅
266
- ( 13.32 mb … 34.90 mb) 24.06 mb █▁█▁▁████▁▁▁▁▁▁▁▁▁███
267
- 2.90 ipc ( 98.44% cache) 2.44M branch misses
268
- 495.57M cycles 1.44G instructions 56.61M c-refs 881.60k c-misses
269
-
270
- deno's @std/toml 419.95 ms/iter 428.09 ms █
271
- (408.44 ms … 434.51 ms) 431.58 ms █ █
272
- (182.20 mb … 203.81 mb) 188.26 mb ██▁▁▁█▁█▁▁▁▁▁▁█▁▁██▁█
273
- 3.28 ipc ( 97.22% cache) 6.72M branch misses
274
- 2.27G cycles 7.46G instructions 215.21M c-refs 5.98M c-misses
275
-
276
- node-toml 549.86 ms/iter 559.64 ms █ █
277
- (527.73 ms … 574.83 ms) 571.47 ms ▅▅ █ ▅ ▅ █ ▅ ▅▅
278
- ( 21.62 mb … 74.99 mb) 46.84 mb ██▁█▁█▁▁▁█▁▁▁█▁█▁▁▁██
279
- 4.24 ipc ( 96.62% cache) 6.29M branch misses
280
- 2.95G cycles 12.49G instructions 236.46M c-refs 7.99M c-misses
281
-
282
- js-toml 336.03 ms/iter 328.58 ms █
283
- (310.28 ms … 431.93 ms) 379.93 ms ▅█ ▅
284
- (267.75 mb … 279.44 mb) 273.42 mb ██▁▁▇█▁▁▁▁▁▁▁▁▁▇▁▁▁▁▇
285
- 2.02 ipc ( 94.74% cache) 5.08M branch misses
286
- 1.65G cycles 3.33G instructions 113.18M c-refs 5.95M c-misses
287
-
288
- @decimalturn/toml-patch 186.32 ms/iter 185.91 ms █ █
289
- (178.55 ms … 209.69 ms) 190.20 ms ▅ ▅▅ █ ▅█▅ ▅ ▅
290
- ( 22.18 mb … 62.13 mb) 26.09 mb █▁▁██▁▁▁▁█▁███▁█▁▁▁▁█
291
- 2.90 ipc ( 97.50% cache) 3.72M branch misses
292
- 999.99M cycles 2.90G instructions 120.73M c-refs 3.01M c-misses
429
+ @ltd/j-toml 186.47 ms/iter 184.10 ms ██ █
430
+ (166.25 ms … 284.21 ms) 192.51 ms ▅ ██ █ ▅ ▅ ▅ ▅
431
+ ( 20.29 mb … 55.50 mb) 33.21 mb █▁▁▁██▁█▁▁▁▁█▁█▁▁█▁▁█
432
+ 2.38 ipc ( 97.97% cache) 3.93M branch misses
433
+ 1.04G cycles 2.47G instructions 164.91M c-refs 3.35M c-misses
434
+
435
+ fast-toml 92.50 ms/iter 92.90 ms █ █ █
436
+ (88.55 ms … 101.67 ms) 97.51 ms ▅█ █ █▅ ▅ ▅ ▅
437
+ ( 13.48 mb … 34.99 mb) 24.13 mb ██▁▁▁█▁██▁█▁▁█▁▁▁▁▁▁█
438
+ 2.82 ipc ( 98.12% cache) 2.40M branch misses
439
+ 516.21M cycles 1.45G instructions 67.12M c-refs 1.26M c-misses
440
+
441
+ @std/toml 428.34 ms/iter 434.32 ms █
442
+ (410.50 ms … 446.83 ms) 442.42 ms ▅ ▅█ ▅▅ ▅▅▅ ▅ ▅
443
+ (181.70 mb … 204.21 mb) 194.10 mb █▁▁▁██▁▁▁██▁▁███▁█▁▁█
444
+ 3.08 ipc ( 96.60% cache) 6.52M branch misses
445
+ 2.41G cycles 7.42G instructions 243.62M c-refs 8.29M c-misses
446
+
447
+ toml (Date/string) 557.91 ms/iter 562.12 ms █
448
+ (535.21 ms … 581.06 ms) 577.25 ms █
449
+ ( 34.09 mb … 84.96 mb) 64.32 mb █▁█▁▁█▁▁███▁▁█▁▁█▁▁▁█
450
+ 4.17 ipc ( 96.50% cache) 6.35M branch misses
451
+ 3.07G cycles 12.80G instructions 237.61M c-refs 8.32M c-misses
452
+
453
+ toml (Temporal) 587.43 ms/iter 597.17 ms █
454
+ (570.22 ms … 607.53 ms) 606.15 ms █ █ █
455
+ ( 2.54 mb … 92.29 mb) 56.92 mb █▁▁█▁▁▁█▁▁▁▁▁███▁▁▁▁█
456
+ 4.08 ipc ( 96.20% cache) 6.59M branch misses
457
+ 3.20G cycles 13.03G instructions 261.00M c-refs 9.91M c-misses
458
+
459
+ js-toml 280.63 ms/iter 305.16 ms █
460
+ (248.43 ms … 358.30 ms) 322.18 ms █
461
+ (268.55 mb … 282.47 mb) 272.11 mb ████▁█▁▁▁▁█▁▁▁▁█▁█▁▁█
462
+ 2.17 ipc ( 94.73% cache) 5.06M branch misses
463
+ 1.49G cycles 3.23G instructions 127.90M c-refs 6.74M c-misses
464
+
465
+ @decimalturn/toml-patch (Date) 207.09 ms/iter 212.85 ms █
466
+ (195.68 ms … 235.57 ms) 219.92 ms ██
467
+ ( 5.63 mb … 47.95 mb) 28.68 mb ███▁▁▁▁▁▁▁▁██▁██▁▁▁▁█
468
+ 2.94 ipc ( 97.40% cache) 4.09M branch misses
469
+ 1.13G cycles 3.33G instructions 144.65M c-refs 3.77M c-misses
470
+
471
+ @decimalturn/toml-patch (Temporal) 219.53 ms/iter 217.17 ms ██
472
+ (214.02 ms … 236.49 ms) 233.70 ms ███
473
+ ( 11.24 mb … 56.44 mb) 25.17 mb ████▁▁▁▁▁▁▁▁▁▁█▁▁▁▁▁█
474
+ 2.89 ipc ( 97.08% cache) 4.38M branch misses
475
+ 1.21G cycles 3.50G instructions 166.38M c-refs 4.86M c-misses
293
476
 
294
477
  summary
295
- fast-toml
296
- 1.23x faster than smol-toml
297
- 2.02x faster than @decimalturn/toml-patch
298
- 2.06x faster than @ltd/j-toml
299
- 3.64x faster than js-toml
300
- 4.55x faster than deno's @std/toml
301
- 5.96x faster than node-toml
478
+ smol-toml (Temporal)
479
+ 1.06x faster than smol-toml (Date)
480
+ 2.05x faster than fast-toml
481
+ 4.14x faster than @ltd/j-toml
482
+ 4.6x faster than @decimalturn/toml-patch (Date)
483
+ 4.87x faster than @decimalturn/toml-patch (Temporal)
484
+ 6.23x faster than js-toml
485
+ 9.51x faster than @std/toml
486
+ 12.38x faster than toml (Date/string)
487
+ 13.04x faster than toml (Temporal)
488
+
302
489
  node --expose-gc bench/stringify.bench.ts
303
- clk: ~5.52 GHz
490
+ clk: ~5.38 GHz
304
491
  cpu: AMD Ryzen 9 9950X3D 16-Core Processor
305
- runtime: node 26.5.0 (x64-linux)
492
+ runtime: node 26.10.0 (x64-linux)
306
493
 
307
494
  benchmark avg (min … max) p75 / p99 (min … top 1%)
308
495
  ------------------------------------------- -------------------------------
309
496
  • spec document
310
497
  ------------------------------------------- -------------------------------
311
- smol-toml 2.29 µs/iter 2.30 µs ▅ █
312
- (2.26 µs … 2.33 µs) 2.33 µs ▆▆ ▃▆█ ██▃ ▃
313
- ( 4.28 kb … 4.65 kb) 4.54 kb █████████████▄▆▄▄▁▄▆▄
314
- 4.45 ipc ( 99.40% cache) 5.23 branch misses
315
- 12.67k cycles 56.39k instructions 909.08 c-refs 5.43 c-misses
316
-
317
- @iarna/toml 8.58 µs/iter 8.57 µs █
318
- (8.54 µs … 8.79 µs) 8.63 µs ████ █
319
- (509.76 b … 1.39 kb) 574.04 b █████▁██▁▁▁▁▁▁▁█▁▁▁▁█
320
- 3.99 ipc ( 99.30% cache) 24.95 branch misses
321
- 48.05k cycles 191.70k instructions 6.20k c-refs 43.23 c-misses
322
-
323
- @ltd/j-toml 89.59 µs/iter 89.41 µs █
324
- (70.85 µs … 242.29 µs) 127.85 µs █
325
- ( 4.02 kb … 375.16 kb) 37.41 kb ▁▁▂▂▁▁█▇▃▁▁▁▁▁▁▁▁▁▁▁▁
326
- 4.16 ipc ( 99.69% cache) 721.33 branch misses
327
- 495.22k cycles 2.06M instructions 28.23k c-refs 88.81 c-misses
328
-
329
- deno's @std/toml 3.96 µs/iter 3.96 µs █ ▄ ▄
330
- (3.91 µs … 4.43 µs) 4.01 µs ▅██ █▅█ █
331
- (803.91 b … 3.95 kb) 965.01 b ▅███▅███▅█▅▅▅▅▁▁▁▁▅▁▅
332
- 3.85 ipc ( 99.45% cache) 11.59 branch misses
333
- 22.20k cycles 85.43k instructions 3.02k c-refs 16.58 c-misses
334
-
335
- js-toml 3.69 µs/iter 3.71 µs █ ▄
336
- (3.65 µs … 3.82 µs) 3.77 µs ▅█▅██ █▅█
337
- ( 6.46 kb … 7.23 kb) 7.10 kb ██████▅████▅▁█▁▁▁▅▁▁▅
338
- 4.14 ipc ( 98.79% cache) 11.99 branch misses
339
- 20.62k cycles 85.48k instructions 1.97k c-refs 23.80 c-misses
340
-
341
- @decimalturn/toml-patch 48.60 µs/iter 48.28 µs █
342
- (45.59 µs … 296.88 µs) 81.95 µs █
343
- (128.00 b … 703.46 kb) 93.31 kb ▆█▇▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
344
- 4.05 ipc ( 99.26% cache) 533.40 branch misses
345
- 270.34k cycles 1.09M instructions 37.72k c-refs 278.17 c-misses
498
+ smol-toml 2.68 µs/iter 2.68 µs █
499
+ (2.61 µs … 2.91 µs) 2.89 µs ▅█▇▂
500
+ ( 4.29 kb … 4.39 kb) 4.30 kb ▇████▅▄▄▁▁▁▁▂▂▁▁▁█▂▁▂
501
+ 4.41 ipc ( 99.57% cache) 6.85 branch misses
502
+ 14.77k cycles 65.13k instructions 1.43k c-refs 6.19 c-misses
503
+
504
+ @iarna/toml 9.71 µs/iter 9.66 µs █
505
+ (9.31 µs … 132.37 µs) 11.48 µs ▄█▆
506
+ (232.00 b … 681.09 kb) 26.28 kb ▁███▆▃▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁
507
+ 3.85 ipc ( 99.49% cache) 33.76 branch misses
508
+ 55.12k cycles 212.42k instructions 8.62k c-refs 43.87 c-misses
509
+
510
+ @ltd/j-toml 48.15 µs/iter 47.84 µs █▇
511
+ (38.21 µs … 312.67 µs) 66.76 µs ██
512
+ ( 2.72 kb … 382.48 kb) 35.59 kb ▁▁▁▂▂▁██▄▂▁▁▁▁▁▁▁▁▁▁▁
513
+ 3.86 ipc ( 99.59% cache) 322.22 branch misses
514
+ 270.56k cycles 1.04M instructions 27.49k c-refs 113.85 c-misses
515
+
516
+ @std/toml 4.86 µs/iter 4.60 µs █
517
+ (4.25 µs … 178.46 µs) 8.94 µs █
518
+ (440.00 b … 521.36 kb) 18.02 kb ▄█▅▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
519
+ 3.46 ipc ( 99.31% cache) 21.73 branch misses
520
+ 26.86k cycles 92.81k instructions 4.73k c-refs 32.73 c-misses
521
+
522
+ js-toml 5.76 µs/iter 5.77 µs ▃█
523
+ (5.69 µs … 5.83 µs) 5.81 µs ▂ ▇▂██
524
+ ( 1.94 kb … 7.02 kb) 2.16 kb ▆▁▁▁▁▆▁▆█▆████▆▆▁▆▁▆▆
525
+ 4.34 ipc ( 99.16% cache) 34.91 branch misses
526
+ 32.34k cycles 140.35k instructions 3.29k c-refs 27.55 c-misses
527
+
528
+ @decimalturn/toml-patch 59.57 µs/iter 57.71 µs █
529
+ (53.70 µs … 630.39 µs) 110.05 µs █
530
+ ( 4.04 kb … 1.10 mb) 108.22 kb ▅█▆▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
531
+ 3.94 ipc ( 98.84% cache) 787.33 branch misses
532
+ 333.69k cycles 1.32M instructions 48.19k c-refs 561.33 c-misses
346
533
 
347
534
  summary
348
535
  smol-toml
349
- 1.61x faster than js-toml
350
- 1.73x faster than deno's @std/toml
351
- 3.75x faster than @iarna/toml
352
- 21.25x faster than @decimalturn/toml-patch
353
- 39.18x faster than @ltd/j-toml
536
+ 1.81x faster than @std/toml
537
+ 2.15x faster than js-toml
538
+ 3.62x faster than @iarna/toml
539
+ 17.96x faster than @ltd/j-toml
540
+ 22.22x faster than @decimalturn/toml-patch
354
541
 
355
542
  • 5MB document
356
543
  ------------------------------------------- -------------------------------
357
- smol-toml 45.33 ms/iter 46.14 ms █ █
358
- (42.89 ms … 48.08 ms) 47.97 ms ▅▅ ▅ ▅ █▅ █ ▅ ▅
359
- ( 9.41 mb … 35.68 mb) 12.98 mb ██▁█▁█▁▁██▁▁▁█▁█▁▁▁▁█
360
- 1.98 ipc ( 94.06% cache) 1.62M branch misses
361
- 234.88M cycles 464.38M instructions 12.57M c-refs 746.25k c-misses
362
-
363
- @iarna/toml 130.01 ms/iter 130.79 ms █ █
364
- (127.84 ms … 135.01 ms) 132.06 ms █ ▅█ ▅▅ ▅▅ ▅ ▅
365
- ( 23.69 mb … 51.95 mb) 41.55 mb █▁▁██▁██▁▁▁▁▁██▁▁▁█▁█
366
- 2.54 ipc ( 96.96% cache) 4.31M branch misses
367
- 707.33M cycles 1.80G instructions 73.12M c-refs 2.22M c-misses
368
-
369
- @ltd/j-toml 928.19 ms/iter 933.90 ms █
370
- (903.30 ms … 940.61 ms) 934.55 ms █ █
371
- ( 1.89 mb … 32.62 mb) 12.57 mb █▁▁▁▁▁▁▁▁▁▁█▁▁██▁████
372
- 4.02 ipc ( 99.15% cache) 7.29M branch misses
373
- 5.09G cycles 20.45G instructions 194.29M c-refs 1.66M c-misses
374
-
375
- deno's @std/toml 68.58 ms/iter 70.20 ms █
376
- (63.51 ms … 78.12 ms) 75.83 ms ▅ █
377
- ( 29.19 mb … 62.19 mb) 33.69 mb █▁▁▇▁█▇▁▁▁▁▇▁▁▇▁▁▁▁▁▇
378
- 2.14 ipc ( 94.82% cache) 1.78M branch misses
379
- 341.59M cycles 731.18M instructions 26.60M c-refs 1.38M c-misses
380
-
381
- js-toml 110.26 ms/iter 111.58 ms █
382
- (106.23 ms … 118.30 ms) 116.43 ms █
383
- ( 31.58 mb … 62.06 mb) 43.79 mb ▇▁▇█▇▇▁▁▁▁▇▁▁▁▁▁▁▇▁▁▇
384
- 2.29 ipc ( 96.17% cache) 3.09M branch misses
385
- 596.81M cycles 1.36G instructions 41.90M c-refs 1.60M c-misses
386
-
387
- @decimalturn/toml-patch 933.72 ms/iter 950.61 ms █ █ █
388
- (898.60 ms … 969.27 ms) 955.92 ms █ ▅ ▅▅ ▅ █ ▅ █
389
- (119.41 mb … 147.95 mb) 122.51 mb █▁▁▁▁█▁██▁▁█▁▁▁▁█▁█▁█
390
- 3.20 ipc ( 93.32% cache) 12.50M branch misses
391
- 5.05G cycles 16.18G instructions 694.63M c-refs 46.41M c-misses
544
+ smol-toml 43.72 ms/iter 47.53 ms █ █
545
+ (40.14 ms … 48.06 ms) 47.98 ms █ █ █
546
+ ( 9.39 mb … 35.40 mb) 12.82 mb ███▁▁▁▁▁█▁▁▁▁▁▁▁▁▁▁██
547
+ 2.28 ipc ( 95.29% cache) 1.68M branch misses
548
+ 225.53M cycles 513.97M instructions 15.50M c-refs 730.62k c-misses
549
+
550
+ @iarna/toml 134.59 ms/iter 138.20 ms █
551
+ (126.83 ms … 143.64 ms) 138.71 ms █ █
552
+ ( 28.96 mb … 54.84 mb) 42.86 mb █▁▁▁█▁▁█▁▁█▁▁▁██▁▁▁██
553
+ 2.65 ipc ( 97.36% cache) 4.43M branch misses
554
+ 710.95M cycles 1.88G instructions 84.80M c-refs 2.24M c-misses
555
+
556
+ @ltd/j-toml 383.10 ms/iter 388.05 ms █
557
+ (366.11 ms … 390.91 ms) 389.63 ms █ █ █
558
+ ( 21.44 mb … 22.42 mb) 21.75 mb █▁▁▁▁▁▁▁▁█▁▁██▁▁█▁▁██
559
+ 3.81 ipc ( 99.05% cache) 4.10M branch misses
560
+ 2.08G cycles 7.93G instructions 182.50M c-refs 1.74M c-misses
561
+
562
+ @std/toml 71.01 ms/iter 72.24 ms █
563
+ (62.44 ms … 81.12 ms) 79.64 ms █
564
+ ( 29.44 mb … 62.92 mb) 37.36 mb █▁██▁▁▁██▁██▁▁▁█▁▁▁▁█
565
+ 2.19 ipc ( 95.42% cache) 1.85M branch misses
566
+ 347.81M cycles 761.47M instructions 31.77M c-refs 1.46M c-misses
567
+
568
+ js-toml 107.22 ms/iter 110.20 ms █
569
+ (99.03 ms … 114.64 ms) 112.12 ms █ █ █
570
+ ( 18.56 mb … 48.98 mb) 42.88 mb █▁▁▁▁▁▁▁▁█▁▁▁▁█▁██▁██
571
+ 2.50 ipc ( 96.46% cache) 3.18M branch misses
572
+ 573.52M cycles 1.43G instructions 50.22M c-refs 1.78M c-misses
573
+
574
+ @decimalturn/toml-patch 543.69 ms/iter 570.96 ms █
575
+ (515.23 ms … 583.43 ms) 578.06 ms █
576
+ (112.55 mb … 144.20 mb) 122.09 mb █▁██▁██▁█▁▁▁▁▁▁▁▁▁███
577
+ 3.30 ipc ( 94.93% cache) 7.55M branch misses
578
+ 2.91G cycles 9.59G instructions 234.01M c-refs 11.85M c-misses
392
579
 
393
580
  summary
394
581
  smol-toml
395
- 1.51x faster than deno's @std/toml
396
- 2.43x faster than js-toml
397
- 2.87x faster than @iarna/toml
398
- 20.48x faster than @ltd/j-toml
399
- 20.6x faster than @decimalturn/toml-patch
582
+ 1.62x faster than @std/toml
583
+ 2.45x faster than js-toml
584
+ 3.08x faster than @iarna/toml
585
+ 8.76x faster than @ltd/j-toml
586
+ 12.44x faster than @decimalturn/toml-patch
400
587
  ```
401
588
 
402
589
  </details>
590
+
591
+ [Temporal API]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Temporal
592
+ [`Temporal.Duration`]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration
593
+ [`Temporal.Instant`]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant
594
+ [`Temporal.PlainDate`]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDate
595
+ [`Temporal.PlainDateTime`]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDateTime
596
+ [`Temporal.PlainMonthDay`]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay
597
+ [`Temporal.PlainTime`]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime
598
+ [`Temporal.PlainYearMonth`]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth
599
+ [`Temporal.ZonedDateTime`]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime
600
+
601
+ [toml-lang/toml#514]: https://github.com/toml-lang/toml/issues/514
602
+ [toml-lang/toml#1034]: https://github.com/toml-lang/toml/issues/1034
603
+ [toml-lang/toml#1105]: https://github.com/toml-lang/toml/issues/1105
604
+
605
+ [RFC 9557]: https://www.rfc-editor.org/info/rfc9557