-
Notifications
You must be signed in to change notification settings - Fork 557
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pre-allocate capacity for maps in json! macro. #876
base: master
Are you sure you want to change the base?
Conversation
Actually, I think I could get rid of the duplicated error messages by just returning 0 in the capacity counting part of the macro when a syntax error has occurred, and just letting the actual parsing part of the macro print the actual error message. |
The latest commit makes it so error messages are printed only once (like before) by just returning 0 if an error occurs in the capacity-counting part of the macro. Considering that large enough invocations of this macro are more likely to hit the recursion limit than to cause compilation performance issues, I'm guessing performance is not a big issue here. But anyway, i also did a small performance test. With Without I used the following program with only #![recursion_limit = "16384"]
use serde_json::json;
fn main() {
let _m = include!("../test.json");
} Where import json
import random
ALPHABET: str = "abcdefghijklmnopqrstuvwxyz"
def make_random_key(size: int) -> str:
return ''.join(random.choices(ALPHABET, k=size))
def make_random_map(size: int, max_depth: int) -> dict:
if size <= 1 or max_depth <= 1:
return {make_random_key(4): None for _ in range(size)}
else:
map = {}
count: int = random.randint(1, size)
each: int = size // count
leftover: int = size % count
for i in range(count):
map[make_random_key(4)] = make_random_map(each + (1 if i < leftover else 0), max_depth-1)
return map
def make_random_json(size: int, max_depth: int) -> str:
return json.dumps(make_random_map(size, max_depth))
if __name__ == "__main__":
import sys
size = int(sys.argv[1])
max_depth = int(sys.argv[2])
print("json!{", make_random_json(size, max_depth), "}") |
Attempt to address issue serde-rs#810. This implementation works by expanding the contents of the map twice, first to produce a capacity value, then actually inserting the elements. Because it expands the contents of the map twice, when encountering invalid syntax, it may print error messages twice, which may be unwanted.
…rt errors. Since these errors are already reported by the part of the macro that actually parses the map, it is unnecessary to report them twice, so the capacity-counting part can just return 0 if it encounters an error.
6d18459
to
e976482
Compare
I've rebased onto current master. When I get a chance I'll re-do the performance test. Also, looking back, it'd probably be a good idea to only do this with |
Attempt to resolve #810.
This implementation works by expanding the contents of the map twice, first producing a capacity value, then actually inserting the elements.
Because it expands the contents of the map twice, when encountering invalid syntax, it prints some error messages twice, which may be unwanted.