HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

JSON parser in C#

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
jsonparserstackoverflow

Problem

I've writen a C# JSON parser, but its performance is not as good as JSON.NET.

Running the same test, my parser takes 278 ms and JSON.NET takes 24 ms. What should I do to optimize it? It seems that the dynamic type slows down the lib.

I know this parser doesn't support floats and negative numbers, but it doesn't matter.

JsonObject.cs

public class JsonObject
{
    private readonly Dictionary dict = new Dictionary();

    public void AddKeyValue(string key, dynamic value) {
        dict.Add(key, value);
    }

    public void AddKeyValue(KeyValuePair? pair) {
        if (pair.HasValue)
            dict.Add(pair.Value.Key, pair.Value.Value);
    }

    public dynamic this[string key] {
        get {
            return dict[key];
        }
        set {
            dict[key] = value;
        }
    }

    public static dynamic FromFile(string filename) {
        var lexer = Lexer.FromFile(filename);
        var parser = new Parser(lexer);
        return parser.Parse();
    }

    public static dynamic FromString(string content) {
        var lexer = Lexer.FromString(content);
        var parser = new Parser(lexer);
        return parser.Parse();
    }
}


Parser.cs

```
public class Parser
{
private readonly ParseSupporter _;

public Parser(Lexer lexer) {
_ = new ParseSupporter(lexer);
}

public dynamic Parse() {
if (_.MatchToken(TokenType.SyntaxType, "{")) {
return ParseJsonObject();
}
if (_.MatchToken(TokenType.SyntaxType, "[")) {
return ParseJsonArray();
}
throw new FormatException();
}

private List ParseJsonArray() {
var result = new List();
_.UsingToken(TokenType.SyntaxType, "[");

var value = ParseValue();
while (value != null) {
result.Add(value);
_.UsingToken(TokenType.SyntaxType, ",");
value = ParseValue();
}

_.UsingToken(TokenType.SyntaxType, "]");

return result;

Solution

(It seems like you've improved performance but I hate to see a good question go unanswered)

Questions about performance can really only be answered with measurements, and unfortunately your question doesn't provide a complete enough program to measure. Furthermore, the missing lexer code presents opportunities for sub-optimal performance, e.g. inefficient regular expressions.

One thing that does stand out in your code is the use of dynamic. I don't see you calling any functions on references of type dynamic so you might just be able to replace them with Object or your own json object root type. If you really need to take advantage of dynamic, there is an overhead. As this answer explains, there is a per-site cost and a smaller per-run cost. Benchmark code with too few iterations could exaggerate the setup cost, though real-world usage might not have enough runs through to amortize that.

Context

StackExchange Code Review Q#102644, answer score: 2

Revisions (0)

No revisions yet.