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<string, dynamic> dict = new Dictionary<string, dynamic>();
public void AddKeyValue(string key, dynamic value) {
dict.Add(key, value);
}
public void AddKeyValue(KeyValuePair<string, dynamic>? 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<dynamic> ParseJsonArray() {
var result = new List<dynamic>();
_.UsingToken(TokenType.SyntaxType, "[");
var value = ParseValue();
while (value != null) {
result.Add(value);
_.UsingToken(TokenType.SyntaxType, ",");
value = ParseValue();
}
_.UsingToken(TokenType.SyntaxType, "]");
return result;
}
private JsonObject ParseJsonObject() {
var j = new JsonObject();
_.UsingToken(TokenType.SyntaxType, "{");
var pair = ParsePair();
while (pair != null) {
j.AddKeyValue(pair);
_.UsingToken(TokenType.SyntaxType, ",");
pair = ParsePair();
}
_.UsingToken(TokenType.SyntaxType, "}");
return j;
}
private KeyValuePair<string, dynamic>? ParsePair() {
var key = string.Empty;
{
var token = _.UsingToken(TokenType.StringType);
if (token == null) {
return null;
}
key = token.Value.Value;
}
_.UsingToken(TokenType.SyntaxType, ":");
var value = ParseValue();
if (value == null) {
return null;
}
return new KeyValuePair<string, dynamic>(key, value);
}
private dynamic ParseValue() {
if (_.MatchToken(TokenType.SyntaxType, "{")) {
return ParseJsonObject();
}
if (_.MatchToken(TokenType.SyntaxType, "[")) {
return ParseJsonArray();
}
{
var token = _.UsingTokenExpect(TokenType.SyntaxType);
return token != null ? token.Value.RealValue : null;
}
}
}
_
is the most freaky variable name that I've ever seen ;-] – t3chb0t Sep 3 '15 at 14:50_
– YangFan Sep 4 '15 at 4:01