fastsimdjson 0.4.0__tar.gz → 0.6.0__tar.gz
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.
- {fastsimdjson-0.4.0/src/fastsimdjson.egg-info → fastsimdjson-0.6.0}/PKG-INFO +55 -1
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/README.md +54 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/pyproject.toml +1 -1
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/src/fastsimdjson.cpp +697 -26
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0/src/fastsimdjson.egg-info}/PKG-INFO +55 -1
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/tests/test_stream.py +159 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/MANIFEST.in +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/setup.cfg +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/setup.py +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/src/fastsimdjson.egg-info/SOURCES.txt +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/src/fastsimdjson.egg-info/dependency_links.txt +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/src/fastsimdjson.egg-info/requires.txt +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/src/fastsimdjson.egg-info/top_level.txt +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/tests/test_dumps.py +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/tests/test_files.py +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/tests/test_lazy.py +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/tests/test_loads.py +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/vendor/simdjson.cpp +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/vendor/simdjson.h +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/vendor/simdutf.cpp +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/vendor/simdutf.h +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/vendor/simdutf_c.h +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/vendor/zmij-LICENSE +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/vendor/zmij.cc +0 -0
- {fastsimdjson-0.4.0 → fastsimdjson-0.6.0}/vendor/zmij.h +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastsimdjson
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Fast JSON parsing for Python, built on simdjson
|
|
5
5
|
Author-email: Daniel Lemire <daniel@lemire.me>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -197,6 +197,42 @@ returned, otherwise `JSONDecodeError` reports `json`'s message and the
|
|
|
197
197
|
position in the whole input. A truncated last document is an error. The
|
|
198
198
|
views returned by `parse_many` remain valid after the iterator moves on.
|
|
199
199
|
|
|
200
|
+
### Streams on several threads: `threads=N` and `map_many`
|
|
201
|
+
|
|
202
|
+
On free-threaded Python (3.14t and newer), a stream can be parsed by several
|
|
203
|
+
threads at once:
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
docs = fastsimdjson.loads_many(data, threads=16) # a list, in order
|
|
207
|
+
views = fastsimdjson.parse_many(data, threads=16) # a list of views
|
|
208
|
+
# fn runs in the threads too, on each document; its results, in order:
|
|
209
|
+
scores = fastsimdjson.map_many(score, data, threads=16)
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
With `threads`, `loads_many` and `parse_many` return a list of all the
|
|
213
|
+
documents instead of an iterator. `map_many(fn, data, **kw)` returns
|
|
214
|
+
`[fn(doc) for doc in loads_many(data, **kw)]` (`parse_many` with
|
|
215
|
+
`lazy=True`), with `fn` called in the threads. `threads=0` (or `None`) uses
|
|
216
|
+
one thread per processor; small inputs use fewer threads (about one per
|
|
217
|
+
512 KB). The input is cut into chunks at newlines (before each `\x1e` for
|
|
218
|
+
`json_seq`), so `threads` works with the formats `"whitespace"`, `"lines"`
|
|
219
|
+
and `"json_seq"`.
|
|
220
|
+
|
|
221
|
+
The results, and the exceptions, are those of one thread: when a chunk
|
|
222
|
+
contains an error or a document that only `json` accepts, the documents
|
|
223
|
+
before it are kept and the rest is parsed in the calling thread, as without
|
|
224
|
+
threads. An exception raised by `fn` is raised again, for the first document
|
|
225
|
+
where it happened; `fn` may then have been called on later documents, in
|
|
226
|
+
other threads, and it must be safe to call from several threads at once.
|
|
227
|
+
|
|
228
|
+
The worker threads are started by the first call that needs them and kept
|
|
229
|
+
for later calls (they wait, detached from the interpreter, between calls,
|
|
230
|
+
and stop at exit). `map_many` scales best: each document is built, used and
|
|
231
|
+
freed in the same thread, and only `fn`'s results come back. `loads_many` must return every
|
|
232
|
+
document, and the Python objects of all of them, to the calling thread.
|
|
233
|
+
With the GIL (the default build of Python), the calling thread does all the
|
|
234
|
+
work: `threads` has no effect on speed.
|
|
235
|
+
|
|
200
236
|
### `release`
|
|
201
237
|
|
|
202
238
|
`release()` frees the simdjson parser and the string caches kept by the
|
|
@@ -433,6 +469,24 @@ msgspec's `decode_lines` and `loads_many` are on par (`loads_many` is about 2%
|
|
|
433
469
|
faster). `parse_many` only creates the views; reading values from them adds to
|
|
434
470
|
its time.
|
|
435
471
|
|
|
472
|
+
### Streams on several threads
|
|
473
|
+
|
|
474
|
+
300 MB of NDJSON (146,624 records: tweets, GitHub events, citm performances,
|
|
475
|
+
gsoc and update-center entries), free-threaded Python 3.14.6, collector
|
|
476
|
+
disabled (see below), Intel Xeon Gold 6548N (64 cores); GB/s:
|
|
477
|
+
|
|
478
|
+
| threads | 1 | 2 | 4 | 8 | 16 | 32 | 64 |
|
|
479
|
+
|---|---:|---:|---:|---:|---:|---:|---:|
|
|
480
|
+
| `map_many(len, data, threads=N)` | 1.03 | 1.78 | 3.66 | 6.82 | 13.0 | 23.7 | **28.8** |
|
|
481
|
+
| `parse_many(data, threads=N)` | 2.00 | 2.84 | 5.28 | 9.26 | 16.1 | 22.7 | 25.8 |
|
|
482
|
+
| `loads_many(data, threads=N)` | 0.90 | 1.44 | 2.79 | 4.99 | 8.98 | 13.3 | 15.4 |
|
|
483
|
+
|
|
484
|
+
`map_many` is 28 times faster on 64 threads than on one (up to 38 GB/s when
|
|
485
|
+
nothing else runs in the process). `loads_many` builds every document for
|
|
486
|
+
the calling thread and is 17 times faster. With the collector enabled,
|
|
487
|
+
Python collects after the call returns: it examines the millions of objects
|
|
488
|
+
just created, which takes about 0.1 s here, with or without threads.
|
|
489
|
+
|
|
436
490
|
## Limitations
|
|
437
491
|
|
|
438
492
|
* The simdjson parser and the key and string caches are thread-local.
|
|
@@ -166,6 +166,42 @@ returned, otherwise `JSONDecodeError` reports `json`'s message and the
|
|
|
166
166
|
position in the whole input. A truncated last document is an error. The
|
|
167
167
|
views returned by `parse_many` remain valid after the iterator moves on.
|
|
168
168
|
|
|
169
|
+
### Streams on several threads: `threads=N` and `map_many`
|
|
170
|
+
|
|
171
|
+
On free-threaded Python (3.14t and newer), a stream can be parsed by several
|
|
172
|
+
threads at once:
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
docs = fastsimdjson.loads_many(data, threads=16) # a list, in order
|
|
176
|
+
views = fastsimdjson.parse_many(data, threads=16) # a list of views
|
|
177
|
+
# fn runs in the threads too, on each document; its results, in order:
|
|
178
|
+
scores = fastsimdjson.map_many(score, data, threads=16)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
With `threads`, `loads_many` and `parse_many` return a list of all the
|
|
182
|
+
documents instead of an iterator. `map_many(fn, data, **kw)` returns
|
|
183
|
+
`[fn(doc) for doc in loads_many(data, **kw)]` (`parse_many` with
|
|
184
|
+
`lazy=True`), with `fn` called in the threads. `threads=0` (or `None`) uses
|
|
185
|
+
one thread per processor; small inputs use fewer threads (about one per
|
|
186
|
+
512 KB). The input is cut into chunks at newlines (before each `\x1e` for
|
|
187
|
+
`json_seq`), so `threads` works with the formats `"whitespace"`, `"lines"`
|
|
188
|
+
and `"json_seq"`.
|
|
189
|
+
|
|
190
|
+
The results, and the exceptions, are those of one thread: when a chunk
|
|
191
|
+
contains an error or a document that only `json` accepts, the documents
|
|
192
|
+
before it are kept and the rest is parsed in the calling thread, as without
|
|
193
|
+
threads. An exception raised by `fn` is raised again, for the first document
|
|
194
|
+
where it happened; `fn` may then have been called on later documents, in
|
|
195
|
+
other threads, and it must be safe to call from several threads at once.
|
|
196
|
+
|
|
197
|
+
The worker threads are started by the first call that needs them and kept
|
|
198
|
+
for later calls (they wait, detached from the interpreter, between calls,
|
|
199
|
+
and stop at exit). `map_many` scales best: each document is built, used and
|
|
200
|
+
freed in the same thread, and only `fn`'s results come back. `loads_many` must return every
|
|
201
|
+
document, and the Python objects of all of them, to the calling thread.
|
|
202
|
+
With the GIL (the default build of Python), the calling thread does all the
|
|
203
|
+
work: `threads` has no effect on speed.
|
|
204
|
+
|
|
169
205
|
### `release`
|
|
170
206
|
|
|
171
207
|
`release()` frees the simdjson parser and the string caches kept by the
|
|
@@ -402,6 +438,24 @@ msgspec's `decode_lines` and `loads_many` are on par (`loads_many` is about 2%
|
|
|
402
438
|
faster). `parse_many` only creates the views; reading values from them adds to
|
|
403
439
|
its time.
|
|
404
440
|
|
|
441
|
+
### Streams on several threads
|
|
442
|
+
|
|
443
|
+
300 MB of NDJSON (146,624 records: tweets, GitHub events, citm performances,
|
|
444
|
+
gsoc and update-center entries), free-threaded Python 3.14.6, collector
|
|
445
|
+
disabled (see below), Intel Xeon Gold 6548N (64 cores); GB/s:
|
|
446
|
+
|
|
447
|
+
| threads | 1 | 2 | 4 | 8 | 16 | 32 | 64 |
|
|
448
|
+
|---|---:|---:|---:|---:|---:|---:|---:|
|
|
449
|
+
| `map_many(len, data, threads=N)` | 1.03 | 1.78 | 3.66 | 6.82 | 13.0 | 23.7 | **28.8** |
|
|
450
|
+
| `parse_many(data, threads=N)` | 2.00 | 2.84 | 5.28 | 9.26 | 16.1 | 22.7 | 25.8 |
|
|
451
|
+
| `loads_many(data, threads=N)` | 0.90 | 1.44 | 2.79 | 4.99 | 8.98 | 13.3 | 15.4 |
|
|
452
|
+
|
|
453
|
+
`map_many` is 28 times faster on 64 threads than on one (up to 38 GB/s when
|
|
454
|
+
nothing else runs in the process). `loads_many` builds every document for
|
|
455
|
+
the calling thread and is 17 times faster. With the collector enabled,
|
|
456
|
+
Python collects after the call returns: it examines the millions of objects
|
|
457
|
+
just created, which takes about 0.1 s here, with or without threads.
|
|
458
|
+
|
|
405
459
|
## Limitations
|
|
406
460
|
|
|
407
461
|
* The simdjson parser and the key and string caches are thread-local.
|