@node-core/utils 7.4.0 → 7.4.1

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.
Files changed (32) hide show
  1. package/lib/update-v8/deps.js +4 -1
  2. package/node_modules/branch-diff/.github/dependabot.yml +14 -2
  3. package/node_modules/branch-diff/.github/workflows/test-and-release.yml +4 -15
  4. package/node_modules/branch-diff/CHANGELOG.md +24 -0
  5. package/node_modules/branch-diff/package.json +35 -3
  6. package/node_modules/js-yaml/dist/browser/js-yaml.esm.min.mjs +2 -2
  7. package/node_modules/js-yaml/dist/browser/js-yaml.esm.min.mjs.map +1 -1
  8. package/node_modules/js-yaml/dist/browser/js-yaml.umd.min.js +1 -1
  9. package/node_modules/js-yaml/dist/browser/js-yaml.umd.min.js.map +1 -1
  10. package/node_modules/js-yaml/dist/js-yaml.cjs.js +2 -1
  11. package/node_modules/js-yaml/dist/js-yaml.cjs.js.map +1 -1
  12. package/node_modules/js-yaml/dist/js-yaml.mjs +2 -1
  13. package/node_modules/js-yaml/dist/js-yaml.mjs.map +1 -1
  14. package/node_modules/js-yaml/package.json +1 -1
  15. package/node_modules/smol-toml/README.md +460 -273
  16. package/node_modules/smol-toml/dist/date.js +50 -21
  17. package/node_modules/smol-toml/dist/error.d.ts +1 -2
  18. package/node_modules/smol-toml/dist/error.js +6 -2
  19. package/node_modules/smol-toml/dist/extract.js +240 -20
  20. package/node_modules/smol-toml/dist/index.cjs +409 -373
  21. package/node_modules/smol-toml/dist/index.d.ts +5 -4
  22. package/node_modules/smol-toml/dist/index.js +2 -1
  23. package/node_modules/smol-toml/dist/parse.d.ts +38 -1
  24. package/node_modules/smol-toml/dist/parse.js +52 -37
  25. package/node_modules/smol-toml/dist/primitive.js +23 -110
  26. package/node_modules/smol-toml/dist/stringify.d.ts +2 -1
  27. package/node_modules/smol-toml/dist/stringify.js +74 -36
  28. package/node_modules/smol-toml/dist/struct.js +76 -99
  29. package/node_modules/smol-toml/dist/util.d.ts +6 -1
  30. package/node_modules/smol-toml/dist/util.js +4 -36
  31. package/node_modules/smol-toml/package.json +8 -8
  32. package/package.json +1 -1
@@ -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 [Temporal API] for representing other types (or alternatively the legacy [`TomlDate` object](#dates)).
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,23 +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 emit
105
- objects from the Temporal API, but for now it only supports `Date` when parsing. When stringifying, `smol-toml` does
106
- support objects from the [Temporal API] and will output the appropriate TOML type.
138
+ ### Date, Time, and Datetime
107
139
 
108
- > [!IMPORTANT]
109
- > If you create a `ZonedDateTime` with a timezone, it will be turned into an offset date-time; losing its precise timezone.
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).
110
146
  >
111
- > For instance, if you create one with the timezone `Europe/Paris`, it'll be turned into an offset date-time `+02:00`
112
- > or `+01:00`, depending on the offset observed at the instant referred to by the date-time.
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.
113
150
  >
114
- > ```js
115
- > Temporal.ZonedDateTime.from({ year: 2001, month: 9, day: 21, hour: 10, minute: 17, second: 0, timeZone: 'Europe/Paris' }).toString({ timeZoneName: 'never' })
116
- > // 2001-09-21T10:17:00+02:00
117
- > Temporal.ZonedDateTime.from({ year: 2012, month: 3, day: 19, hour: 8, minute: 0, second: 0, timeZone: 'Europe/Paris' }).toString({ timeZoneName: 'never' })
118
- > // 2012-03-19T08:00:00+01:00
119
- > ```
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.
120
209
 
121
210
  ```js
122
211
  import { TomlDate } from 'smol-toml'
@@ -157,262 +246,360 @@ const localTime = TomlDate.wrapAsLocalTime(jsDate)
157
246
  ```
158
247
 
159
248
  ## Performance
160
- The benchmark is ran using [mitata](https://github.com/evanwashere/mitata).
161
-
162
- Parsers and serializers are tested in 2 scenarios: using the example from TOML's homepage and specification, and
163
- using a ~5MB randomly generated[^generator] file.
164
-
165
- [^generator]: The TOML generator used can be found [here](https://gist.github.com/cyyynthia/e77c744cb6494dabe37d0182506526b9)
166
-
167
- While `fast-toml` is included as it's a challenging candidate, it takes a lot of shortcuts that makes it very fast,
168
- but at the expense of correctness (it has significant defects and does not pass the TOML test suite). `smol-toml` is
169
- almost as fast, without sacrificing correctness. 😎
170
-
171
- | **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 |
172
- |----------------|--------------------|-------------------|--------------------|-------------------|------------------|----------------|----------------|-------------------------------|
173
- | 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 |
174
- | ~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 |
175
-
176
- | **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 |
177
- |----------------|--------------------|-------------------|--------------------|-----------------|------------------|----------------|----------------|-------------------------------|
178
- | 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] |
179
- | ~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] |
180
-
181
- [^toml-patch-note]: Stringify performance is not included here, as the library is not meant to be fast, but rather
182
- capable of doing precise non-destructive edits that preserve the entire document's shape and format. Putting it here
183
- 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
184
316
 
185
317
  <details>
186
318
  <summary>Detailed benchmark data</summary>
187
319
 
188
320
  ```
189
321
  node --expose-gc bench/parse.bench.ts
190
- clk: ~5.52 GHz
322
+ clk: ~5.39 GHz
191
323
  cpu: AMD Ryzen 9 9950X3D 16-Core Processor
192
- runtime: node 26.5.0 (x64-linux)
324
+ runtime: node 26.10.0 (x64-linux)
193
325
 
194
- benchmark avg (min … max) p75 / p99 (min … top 1%)
195
- ------------------------------------------- -------------------------------
326
+ benchmark avg (min … max) p75 / p99 (min … top 1%)
327
+ ------------------------------------------------- -------------------------------
196
328
  • spec document
197
- ------------------------------------------- -------------------------------
198
- smol-toml 4.16 µs/iter 4.14 µs █
199
- (3.99 µs … 91.94 µs) 4.95 µs ▂█▃
200
- ( 1.41 kb … 417.70 kb) 9.63 kb ▁███▅▃▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁
201
- 4.01 ipc ( 99.54% cache) 19.70 branch misses
202
- 23.81k cycles 95.44k instructions 3.05k c-refs 14.12 c-misses
203
-
204
- @iarna/toml 12.13 µs/iter 12.04 µs █
205
- (11.59 µs … 133.43 µs) 15.94 µs █▄
206
- ( 0.00 b … 677.01 kb) 24.08 kb ▃██▄▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
207
- 3.97 ipc ( 99.63% cache) 75.32 branch misses
208
- 68.16k cycles 270.90k instructions 10.39k c-refs 38.82 c-misses
209
-
210
- @ltd/j-toml 30.44 µs/iter 29.57 µs █
211
- (28.19 µs … 1.18 ms) 44.30 µs █▅
212
- (432.00 b … 692.05 kb) 27.57 kb ▂██▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
213
- 3.42 ipc ( 99.37% cache) 284.51 branch misses
214
- 169.50k cycles 579.61k instructions 25.59k c-refs 162.02 c-misses
215
-
216
- fast-toml 5.01 µs/iter 4.98 µs ▄█
217
- (4.75 µs … 90.47 µs) 5.84 µs ██▃
218
- (336.00 b … 302.06 kb) 12.56 kb ▁▅███▆▅▃▂▂▁▁▁▁▁▁▁▁▁▁▁
219
- 4.40 ipc ( 99.53% cache) 25.73 branch misses
220
- 28.21k cycles 124.23k instructions 3.76k c-refs 17.82 c-misses
221
-
222
- deno's @std/toml 22.34 µs/iter 22.15 µs █▅
223
- (20.78 µs … 155.43 µs) 36.68 µs ██
224
- ( 1.52 kb … 547.05 kb) 64.73 kb ▂██▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
225
- 3.80 ipc ( 99.53% cache) 111.24 branch misses
226
- 124.05k cycles 471.06k instructions 21.13k c-refs 100.20 c-misses
227
-
228
- node-toml 32.28 µs/iter 31.78 µs █
229
- (30.33 µs … 221.49 µs) 53.65 µs █
230
- ( 2.00 kb … 968.27 kb) 109.52 kb ▆█▄▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
231
- 3.89 ipc ( 99.18% cache) 193.02 branch misses
232
- 178.72k cycles 695.61k instructions 29.40k c-refs 240.75 c-misses
233
-
234
- js-toml 24.71 µs/iter 23.17 µs ▅█
235
- (21.20 µs … 731.20 µs) 39.47 µs ██
236
- (744.00 b … 861.36 kb) 92.95 kb ▂██▅▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁
237
- 3.79 ipc ( 98.12% cache) 205.75 branch misses
238
- 134.81k cycles 510.43k instructions 19.00k c-refs 357.65 c-misses
239
-
240
- @decimalturn/toml-patch 17.07 µs/iter 16.85 µs █▆
241
- (15.93 µs … 224.97 µs) 23.30 µs ██
242
- (632.00 b … 635.14 kb) 55.51 kb ▂██▇▃▂▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁
243
- 3.56 ipc ( 99.37% cache) 73.96 branch misses
244
- 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
245
395
 
246
396
  summary
247
- smol-toml
248
- 1.2x faster than fast-toml
249
- 2.92x faster than @iarna/toml
250
- 4.1x faster than @decimalturn/toml-patch
251
- 5.37x faster than deno's @std/toml
252
- 5.94x faster than js-toml
253
- 7.31x faster than @ltd/j-toml
254
- 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)
255
408
 
256
409
  • 5MB document
257
- ------------------------------------------- -------------------------------
258
- smol-toml 113.76 ms/iter 115.67 ms █ █ █
259
- (106.25 ms … 121.53 ms) 118.63 ms ▅ █ ▅ █ ▅ █ ▅ ▅
260
- ( 37.31 mb … 49.50 mb) 43.97 mb █▁▁▁▁█▁▁▁█▁█▁█▁█▁█▁▁█
261
- 2.47 ipc ( 98.58% cache) 3.12M branch misses
262
- 606.38M cycles 1.50G instructions 78.32M c-refs 1.11M c-misses
263
-
264
- @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:
265
424
  4: NfF6LuAerfn5mDPI7Cp 2qsrB4vGmJTyb5jNubOIBYYWrWlAsrw PX93S57gjb5GEhR8qOU5blDQmwfVJTA YvmJ9cE3cUZU NAJQgAbIdpZLhc4lOs4ZhMEWehhZqXCsVD1YP1vN2GEoM2WX''', 1986-05-27T18:36:13Z, -5460, "2ZAV3fYlb23hf7r7QoftVlicWE2iuwp", 4790.2253 ]
266
425
  5> SzeC4Me8T = [ 5928.9340, 1991-04-28 19:24:24, 7807, -782.4516, 0b1000011111, "YvXRZKBGle9d51sqE90t8hP" ]
267
426
  ^
268
427
  6: SLMvBirT.pmpX1D.9PivpfFBo = 2010-09-29
269
428
 
270
-
271
-
272
- @ltd/j-toml 189.89 ms/iter 197.10 ms ██ █
273
- (172.17 ms … 237.08 ms) 210.60 ms ▅ ▅██ ▅ ▅ █ ▅
274
- ( 19.71 mb … 56.03 mb) 36.30 mb █▁███▁█▁▁█▁▁▁█▁▁▁▁▁▁█
275
- 2.41 ipc ( 97.92% cache) 3.88M branch misses
276
- 1.03G cycles 2.49G instructions 143.96M c-refs 3.00M c-misses
277
-
278
- fast-toml 92.24 ms/iter 95.41 ms █ █
279
- (88.83 ms … 96.21 ms) 96.00 ms █ ▅ ▅▅█▅ ▅▅▅
280
- ( 13.32 mb … 34.90 mb) 24.06 mb █▁█▁▁████▁▁▁▁▁▁▁▁▁███
281
- 2.90 ipc ( 98.44% cache) 2.44M branch misses
282
- 495.57M cycles 1.44G instructions 56.61M c-refs 881.60k c-misses
283
-
284
- deno's @std/toml 419.95 ms/iter 428.09 ms █
285
- (408.44 ms … 434.51 ms) 431.58 ms █ █
286
- (182.20 mb … 203.81 mb) 188.26 mb ██▁▁▁█▁█▁▁▁▁▁▁█▁▁██▁█
287
- 3.28 ipc ( 97.22% cache) 6.72M branch misses
288
- 2.27G cycles 7.46G instructions 215.21M c-refs 5.98M c-misses
289
-
290
- node-toml 549.86 ms/iter 559.64 ms █ █
291
- (527.73 ms … 574.83 ms) 571.47 ms ▅▅ █ ▅ ▅ █ ▅ ▅▅
292
- ( 21.62 mb … 74.99 mb) 46.84 mb ██▁█▁█▁▁▁█▁▁▁█▁█▁▁▁██
293
- 4.24 ipc ( 96.62% cache) 6.29M branch misses
294
- 2.95G cycles 12.49G instructions 236.46M c-refs 7.99M c-misses
295
-
296
- js-toml 336.03 ms/iter 328.58 ms █
297
- (310.28 ms … 431.93 ms) 379.93 ms ▅█ ▅
298
- (267.75 mb … 279.44 mb) 273.42 mb ██▁▁▇█▁▁▁▁▁▁▁▁▁▇▁▁▁▁▇
299
- 2.02 ipc ( 94.74% cache) 5.08M branch misses
300
- 1.65G cycles 3.33G instructions 113.18M c-refs 5.95M c-misses
301
-
302
- @decimalturn/toml-patch 186.32 ms/iter 185.91 ms █ █
303
- (178.55 ms … 209.69 ms) 190.20 ms ▅ ▅▅ █ ▅█▅ ▅ ▅
304
- ( 22.18 mb … 62.13 mb) 26.09 mb █▁▁██▁▁▁▁█▁███▁█▁▁▁▁█
305
- 2.90 ipc ( 97.50% cache) 3.72M branch misses
306
- 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
307
476
 
308
477
  summary
309
- fast-toml
310
- 1.23x faster than smol-toml
311
- 2.02x faster than @decimalturn/toml-patch
312
- 2.06x faster than @ltd/j-toml
313
- 3.64x faster than js-toml
314
- 4.55x faster than deno's @std/toml
315
- 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
+
316
489
  node --expose-gc bench/stringify.bench.ts
317
- clk: ~5.52 GHz
490
+ clk: ~5.38 GHz
318
491
  cpu: AMD Ryzen 9 9950X3D 16-Core Processor
319
- runtime: node 26.5.0 (x64-linux)
492
+ runtime: node 26.10.0 (x64-linux)
320
493
 
321
494
  benchmark avg (min … max) p75 / p99 (min … top 1%)
322
495
  ------------------------------------------- -------------------------------
323
496
  • spec document
324
497
  ------------------------------------------- -------------------------------
325
- smol-toml 2.29 µs/iter 2.30 µs ▅ █
326
- (2.26 µs … 2.33 µs) 2.33 µs ▆▆ ▃▆█ ██▃ ▃
327
- ( 4.28 kb … 4.65 kb) 4.54 kb █████████████▄▆▄▄▁▄▆▄
328
- 4.45 ipc ( 99.40% cache) 5.23 branch misses
329
- 12.67k cycles 56.39k instructions 909.08 c-refs 5.43 c-misses
330
-
331
- @iarna/toml 8.58 µs/iter 8.57 µs █
332
- (8.54 µs … 8.79 µs) 8.63 µs ████ █
333
- (509.76 b … 1.39 kb) 574.04 b █████▁██▁▁▁▁▁▁▁█▁▁▁▁█
334
- 3.99 ipc ( 99.30% cache) 24.95 branch misses
335
- 48.05k cycles 191.70k instructions 6.20k c-refs 43.23 c-misses
336
-
337
- @ltd/j-toml 89.59 µs/iter 89.41 µs █
338
- (70.85 µs … 242.29 µs) 127.85 µs █
339
- ( 4.02 kb … 375.16 kb) 37.41 kb ▁▁▂▂▁▁█▇▃▁▁▁▁▁▁▁▁▁▁▁▁
340
- 4.16 ipc ( 99.69% cache) 721.33 branch misses
341
- 495.22k cycles 2.06M instructions 28.23k c-refs 88.81 c-misses
342
-
343
- deno's @std/toml 3.96 µs/iter 3.96 µs █ ▄ ▄
344
- (3.91 µs … 4.43 µs) 4.01 µs ▅██ █▅█ █
345
- (803.91 b … 3.95 kb) 965.01 b ▅███▅███▅█▅▅▅▅▁▁▁▁▅▁▅
346
- 3.85 ipc ( 99.45% cache) 11.59 branch misses
347
- 22.20k cycles 85.43k instructions 3.02k c-refs 16.58 c-misses
348
-
349
- js-toml 3.69 µs/iter 3.71 µs █ ▄
350
- (3.65 µs … 3.82 µs) 3.77 µs ▅█▅██ █▅█
351
- ( 6.46 kb … 7.23 kb) 7.10 kb ██████▅████▅▁█▁▁▁▅▁▁▅
352
- 4.14 ipc ( 98.79% cache) 11.99 branch misses
353
- 20.62k cycles 85.48k instructions 1.97k c-refs 23.80 c-misses
354
-
355
- @decimalturn/toml-patch 48.60 µs/iter 48.28 µs █
356
- (45.59 µs … 296.88 µs) 81.95 µs █
357
- (128.00 b … 703.46 kb) 93.31 kb ▆█▇▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
358
- 4.05 ipc ( 99.26% cache) 533.40 branch misses
359
- 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
360
533
 
361
534
  summary
362
535
  smol-toml
363
- 1.61x faster than js-toml
364
- 1.73x faster than deno's @std/toml
365
- 3.75x faster than @iarna/toml
366
- 21.25x faster than @decimalturn/toml-patch
367
- 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
368
541
 
369
542
  • 5MB document
370
543
  ------------------------------------------- -------------------------------
371
- smol-toml 45.33 ms/iter 46.14 ms █ █
372
- (42.89 ms … 48.08 ms) 47.97 ms ▅▅ ▅ ▅ █▅ █ ▅ ▅
373
- ( 9.41 mb … 35.68 mb) 12.98 mb ██▁█▁█▁▁██▁▁▁█▁█▁▁▁▁█
374
- 1.98 ipc ( 94.06% cache) 1.62M branch misses
375
- 234.88M cycles 464.38M instructions 12.57M c-refs 746.25k c-misses
376
-
377
- @iarna/toml 130.01 ms/iter 130.79 ms █ █
378
- (127.84 ms … 135.01 ms) 132.06 ms █ ▅█ ▅▅ ▅▅ ▅ ▅
379
- ( 23.69 mb … 51.95 mb) 41.55 mb █▁▁██▁██▁▁▁▁▁██▁▁▁█▁█
380
- 2.54 ipc ( 96.96% cache) 4.31M branch misses
381
- 707.33M cycles 1.80G instructions 73.12M c-refs 2.22M c-misses
382
-
383
- @ltd/j-toml 928.19 ms/iter 933.90 ms █
384
- (903.30 ms … 940.61 ms) 934.55 ms █ █
385
- ( 1.89 mb … 32.62 mb) 12.57 mb █▁▁▁▁▁▁▁▁▁▁█▁▁██▁████
386
- 4.02 ipc ( 99.15% cache) 7.29M branch misses
387
- 5.09G cycles 20.45G instructions 194.29M c-refs 1.66M c-misses
388
-
389
- deno's @std/toml 68.58 ms/iter 70.20 ms █
390
- (63.51 ms … 78.12 ms) 75.83 ms ▅ █
391
- ( 29.19 mb … 62.19 mb) 33.69 mb █▁▁▇▁█▇▁▁▁▁▇▁▁▇▁▁▁▁▁▇
392
- 2.14 ipc ( 94.82% cache) 1.78M branch misses
393
- 341.59M cycles 731.18M instructions 26.60M c-refs 1.38M c-misses
394
-
395
- js-toml 110.26 ms/iter 111.58 ms █
396
- (106.23 ms … 118.30 ms) 116.43 ms █
397
- ( 31.58 mb … 62.06 mb) 43.79 mb ▇▁▇█▇▇▁▁▁▁▇▁▁▁▁▁▁▇▁▁▇
398
- 2.29 ipc ( 96.17% cache) 3.09M branch misses
399
- 596.81M cycles 1.36G instructions 41.90M c-refs 1.60M c-misses
400
-
401
- @decimalturn/toml-patch 933.72 ms/iter 950.61 ms █ █ █
402
- (898.60 ms … 969.27 ms) 955.92 ms █ ▅ ▅▅ ▅ █ ▅ █
403
- (119.41 mb … 147.95 mb) 122.51 mb █▁▁▁▁█▁██▁▁█▁▁▁▁█▁█▁█
404
- 3.20 ipc ( 93.32% cache) 12.50M branch misses
405
- 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
406
579
 
407
580
  summary
408
581
  smol-toml
409
- 1.51x faster than deno's @std/toml
410
- 2.43x faster than js-toml
411
- 2.87x faster than @iarna/toml
412
- 20.48x faster than @ltd/j-toml
413
- 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
414
587
  ```
415
588
 
416
589
  </details>
417
590
 
418
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