23 ms·
sscanf is essentially being used as a tokenizer for the JSON grammar, which means something like this: {"foo": "bar"} Is potentially turning into 5 differ
by ddtaylor 4y ago
sscanf is essentially being used as a tokenizer for the JSON grammar, which means something like this:
{"foo": "bar"}
Is potentially turning into 5 different tokens:
{
"foo"
:
"bar"
}
After each token the "state" of sscanf is being discarded and each invocation of sscanf is independent. The API simply isn't descriptive enough to know that a string is immutable and hasn't been changed and there are certainly many valid use cases where one might be re-using the same char[] buffer with different contents.
- tialaramex 4y agoEven with the cache, calculating strlen() just once was already a waste. The JSON to be parsed was read in from somewhere, either a file or received over the network. When that happened the machine knew how long it was. One of the few places where C++ is sometimes better about things than Rust is providing information gathered which is ancillary to the direct purpose, in case you wanted it, so that you needn't then ask for the same information a moment later. In Rust this information may have a difficult to ascertain lifespan, and so it's dangerous, but in C++ they figure the out-of-date nature of the report is your problem. Sometimes to your detriment of course, but often you could really have used that and must now go measure it yourself because the thing you just called knew it but didn't tell you. Here though it wouldn't matter, Rust's array types, and both the owned mutable String and reference &str types know how long they are, so you are never flailing about counting even once. You also would just serde_json this data in Rust because serde is practically part of the Rust Standard Library, whereas there's nothing quite so ubiquitous in C or C++.
- whizzter 4y agoHow much "state" would sscanf really need? From memory (and with an extra peek at the man page) each directive is in sequence of the "format" specifier is sequential (it's not nearly as flexible as a Regexp) so you really only need: A: a processing state (int/enum). B: a current fmt str pointer. C: va_list struct to keep track of destinations. D: a source string pointer. Now if what I saw mentioned in another comment is true that there is some insane conversion to a FILE* stream to do this, then yes I can see why it happens but it's not really NEEDED to implement the function as specified.