HipJSON: A high performance implementation of JSON parser with std.json syntax. Used by Redub and Hipreme Engine

Hipreme msnmancini at hotmail.com
Sat Nov 1 03:43:02 UTC 2025


On Thursday, 30 October 2025 at 16:40:54 UTC, Dennis wrote:
> On Thursday, 30 October 2025 at 13:02:16 UTC, Hipreme wrote:
>> Redub uses a cache system in which the hash of an object 
>> becomes a key. This does not translate well to structs as they 
>> are "random" keys. (...)
>
> So you have several use cases where the keys are not a small 
> set known ahead of time, but constructed dynamically. Makes 
> sense, though now I wonder why you would use JSON for your 
> cache or filesystem when performance is such a concern. Or when 
> it's not a concern, why std.json doesn't suffice.
>
>> There is another case in which the dynamic type API is kinda 
>> important, which is mostly when you do union types, so one 
>> would still need a good representation of it:
>
> You could define:
>
> ```D
> struct Input
> {
>     string keyboard;
>     string gamepad;
>     string analog;
>     string axis;
> }
> ```
>
> And then check the length of those strings to see if they have 
> a value.
>
> Either way, it's still useful to have a fast JSON parser using 
> dynamic objects, and using std.json's API makes it an easy 
> upgrade.

The reasons for why std.json didn't suffice:
- It uses a bunch of phobos dependencies which I can't use since 
I target multiple platforms with Hipreme Engine
- Redub started using hipjson because I found out that it was 
going way faster than std.json even though that meant I would use 
std.conv.to or other phobos functions
- I made that project available because I found out it was the 
fastest implementation for dynamic JSON objects in D
- After that, I grew a little nerdy on that and then made up 
d-segmmented-hashmap which was my response in going even further


Right now, HipJSON just release v1.0.1 which also supports 
streaming API:

```d
import hip.data.json;
import std.exception;
JSONValue myJson;
JSONParseState state = JSONParseState.initialize(0);
enforce(JSONValue.parseStream(myJson, state, `{`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `"`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `h`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `e`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `l`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `l`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `o`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `"`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `:`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, ` `) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `"`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `w`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `o`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `r`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `l`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `d`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `"`) == 
JSONValue.IncompleteStream);
enforce(JSONValue.parseStream(myJson, state, `}`) != 
JSONValue.IncompleteStream);
import std.stdio;
writeln(myJson); //{"hello" : "world"}
```
What was more of a POC also wasn't that hard to get done, though 
I've got some bugfixes and even more performance improvement


More information about the Digitalmars-d-announce mailing list