Skip to content

json.loads(something) performs many times faster if you call json.dumps(None) first #8728

Open
@robogame-dev

Description

@robogame-dev

CircuitPython version

Adafruit CircuitPython 8.2.9 on 2023-12-06; FeatherS3 with ESP32S3

Code/REPL

import json
import time

datastr = json.dumps([111, 222, 333, 444, 555] * 10)


# somehow slower than loads_plus_dumps
def loads_alone(datastr):
    return json.loads(datastr)


# somehow faster than loads_alone
def loads_plus_dumps(datastr):
    json.dumps(None)  # adding this line boosts performance!?
    return json.loads(datastr)


# test loads
start_ns = time.monotonic_ns()
for i in range(0, 1000):
    loads_alone(datastr)
loads_us = (time.monotonic_ns() - start_ns) // (1_000_000)

# test dumps
start_ns = time.monotonic_ns()
for i in range(0, 1000):
    loads_plus_dumps(datastr)
dumpsloads_us = (time.monotonic_ns() - start_ns) // (1_000_000)

# report results
print("loads alone:     " + str(loads_us) + " us each")
print("dumps + loads:   " + str(dumpsloads_us) + " us each")

Behavior

code.py output:
loads alone:     1544 us each
dumps + loads:   424 us each

Description

This feels like a bug, because one would not expect more lines of code to be faster than the same code with lines omitted.

As it is, it seems like there is no reason to ever call json.loads() on it's own - rather, it should always be paired with a json.dumps(None) call first, to boost it's performance..?

Additional information

I tested these functions on Windows Python 3.8 and got the expected result: that loads_alone is faster, on it's own, than loads_plus_dumps - so this issue is specific either to CircuitPython or MicroPython, but does not apply on desktop python.

A possible resolution would be to modify the json module by wrapping the loads func so that it calls json.dumps(None) itself internally? In the meantime, I'm going to make sure to add empty json.dumps(None) calls ahead of any of my json.loads(..) calls to get the performance boost.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions