Parcourir la source

More performance tuning

Brad Robinson il y a 11 ans
Parent
commit
36557a5680
4 fichiers modifiés avec 164 ajouts et 117 suppressions
  1. 78 29
      PetaJson.cs
  2. 5 0
      PetaJson.sln
  3. 80 87
      PetaJsonEmit.cs
  4. 1 1
      TestCases/Program.cs

+ 78 - 29
PetaJson.cs

@@ -1834,41 +1834,96 @@ namespace PetaJson
                     signed = true;
                     _sb.Append(_currentChar);
                     NextChar();
-                    if (!Char.IsDigit(_currentChar))
+                }
+
+                bool hex = false;
+                if (_currentChar == '0')
+                {
+                    _sb.Append(_currentChar);
+                    NextChar();
+                    if (_currentChar == 'x' || _currentChar == 'X')
                     {
-                        throw new InvalidDataException("syntax error - expected digit to follow negative sign");
+                        _sb.Append(_currentChar);
+                        NextChar();
+                        hex = true;
                     }
                 }
 
-                // Parse all digits
+                bool cont = true;
                 bool fp = false;
-                while (char.IsDigit(_currentChar) || _currentChar == '.' || _currentChar == 'e' || _currentChar == 'E' || _currentChar == 'x' || _currentChar == 'X')
+                while (cont)
                 {
-                    if (_currentChar == 'e' || _currentChar == 'E')
+                    switch (_currentChar)
                     {
-                        fp = true;
-                        _sb.Append(_currentChar);
-
-                        NextChar();
-                        if (_currentChar == '-' || _currentChar == '+')
-                        {
+                        case '0':
+                        case '1':
+                        case '2':
+                        case '3':
+                        case '4':
+                        case '5':
+                        case '6':
+                        case '7':
+                        case '8':
+                        case '9':
                             _sb.Append(_currentChar);
                             NextChar();
-                        }
-                    }
-                    else
-                    {
-                        if (_currentChar == '.')
-                            fp = true;
+                            break;
 
-                        _sb.Append(_currentChar);
-                        NextChar();
+                        case 'A':
+                        case 'a':
+                        case 'B':
+                        case 'b':
+                        case 'C':
+                        case 'c':
+                        case 'D':
+                        case 'd':
+                        case 'F':
+                        case 'f':
+                            if (!hex)
+                                cont = false;
+                            else
+                            {
+                                _sb.Append(_currentChar);
+                                NextChar();
+                            }
+                            break;
+
+                        case '.':
+                            if (hex)
+                            {
+                                cont = false;
+                            }
+                            else
+                            {
+                                fp = true;
+                                _sb.Append(_currentChar);
+                                NextChar();
+                            }
+                            break;
+
+                        case 'E':
+                        case 'e':
+                            if (!hex)
+                            {
+                                fp = true;
+                                _sb.Append(_currentChar);
+                                NextChar();
+                                if (_currentChar == '+' || _currentChar == '-')
+                                {
+                                    _sb.Append(_currentChar);
+                                    NextChar();
+                                }
+                            }
+                            break;
+
+                        default:
+                            cont = false;
+                            break;
                     }
                 }
 
-                Type type = fp ? typeof(double) : (signed ? typeof(long) : typeof(ulong));
-                if (char.IsLetterOrDigit(_currentChar))
-                    throw new InvalidDataException(string.Format("syntax error - invalid character following number '{0}'", _currentChar));
+                 if (char.IsLetterOrDigit(_currentChar))
+                    throw new InvalidDataException(string.Format("syntax error - invalid character following number '{0}'", _sb.ToString()));
 
 
                 String = _sb.ToString();
@@ -1885,13 +1940,7 @@ namespace PetaJson
                 {
                     LiteralKind = LiteralKind.UnsignedInteger;
                 }
-                /*
-                }
-                catch
-                {
-                    throw new InvalidDataException(string.Format("syntax error - incorrectly formatted number '{0}'", _sb.ToString()));
-                }
-                 */
+              
 
             }
 

+ 5 - 0
PetaJson.sln

@@ -5,6 +5,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestCases", "TestCases\Test
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmitDev", "EmitDev\EmitDev.csproj", "{C70C2324-5076-497A-B93F-C3C49DFDB045}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FF86ACF7-E4CB-4873-96CE-CE495873073E}"
+	ProjectSection(SolutionItems) = preProject
+		Performance1.psess = Performance1.psess
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|x86 = Debug|x86

+ 80 - 87
PetaJsonEmit.cs

@@ -286,113 +286,106 @@ namespace PetaJson
                     typeof(double), typeof(float)
                 };
 
-                try
+                // Process all members
+                foreach (var m in ri.Members)
                 {
-                    // Process all members
-                    foreach (var m in ri.Members)
+                    // Ignore write only properties
+                    var pi = m.Member as PropertyInfo;
+                    if (pi != null && pi.GetSetMethod() == null)
                     {
-                        // Ignore write only properties
-                        var pi = m.Member as PropertyInfo;
-                        if (pi != null && pi.GetSetMethod() == null)
-                        {
-                            continue;
-                        }
+                        continue;
+                    }
 
-                        // Create a dynamic method that can do the work
-                        var method = new DynamicMethod("dynamic_parser", null, new Type[] { typeof(IJsonReader), typeof(object) }, true);
-                        var il = method.GetILGenerator();
+                    // Create a dynamic method that can do the work
+                    var method = new DynamicMethod("dynamic_parser", null, new Type[] { typeof(IJsonReader), typeof(object) }, true);
+                    var il = method.GetILGenerator();
 
-                        if (m.KeepInstance)
-                        {
-                            throw new NotImplementedException("Emit KeepInstance not implemented");
-                        }
+                    if (m.KeepInstance)
+                    {
+                        throw new NotImplementedException("Emit KeepInstance not implemented");
+                    }
 
-                        // Load the target
-                        il.Emit(OpCodes.Ldarg_1);
-                        il.Emit(OpCodes.Castclass, type);
+                    // Load the target
+                    il.Emit(OpCodes.Ldarg_1);
+                    il.Emit(OpCodes.Castclass, type);
 
-                        if (m.MemberType == typeof(string))
-                        {
-                            // check we have a string
-                            il.Emit(OpCodes.Ldarg_0);
-                            il.Emit(OpCodes.Call, typeof(Emit).GetMethod("GetLiteralString", new Type[] { typeof(IJsonReader) }));
+                    if (m.MemberType == typeof(string))
+                    {
+                        // check we have a string
+                        il.Emit(OpCodes.Ldarg_0);
+                        il.Emit(OpCodes.Call, typeof(Emit).GetMethod("GetLiteralString", new Type[] { typeof(IJsonReader) }));
 
-                            il.Emit(OpCodes.Ldarg_0);
-                            il.Emit(OpCodes.Callvirt, typeof(IJsonReader).GetMethod("NextToken", new Type[] { }));
-                        }
+                        il.Emit(OpCodes.Ldarg_0);
+                        il.Emit(OpCodes.Callvirt, typeof(IJsonReader).GetMethod("NextToken", new Type[] { }));
+                    }
 
-                        else if (m.MemberType == typeof(bool))
-                        {
-                            il.Emit(OpCodes.Ldarg_0);
-                            il.Emit(OpCodes.Call, typeof(Emit).GetMethod("GetLiteralBool", new Type[] { typeof(IJsonReader) }));
+                    else if (m.MemberType == typeof(bool))
+                    {
+                        il.Emit(OpCodes.Ldarg_0);
+                        il.Emit(OpCodes.Call, typeof(Emit).GetMethod("GetLiteralBool", new Type[] { typeof(IJsonReader) }));
 
-                            il.Emit(OpCodes.Ldarg_0);
-                            il.Emit(OpCodes.Callvirt, typeof(IJsonReader).GetMethod("NextToken", new Type[] { }));
-                        }
+                        il.Emit(OpCodes.Ldarg_0);
+                        il.Emit(OpCodes.Callvirt, typeof(IJsonReader).GetMethod("NextToken", new Type[] { }));
+                    }
 
-                        else if (m.MemberType == typeof(char))
-                        {
-                            il.Emit(OpCodes.Ldarg_0);
-                            il.Emit(OpCodes.Call, typeof(Emit).GetMethod("GetLiteralChar", new Type[] { typeof(IJsonReader) }));
-                            il.Emit(OpCodes.Ldarg_0);
-                            il.Emit(OpCodes.Callvirt, typeof(IJsonReader).GetMethod("NextToken", new Type[] { }));
-                        }
+                    else if (m.MemberType == typeof(char))
+                    {
+                        il.Emit(OpCodes.Ldarg_0);
+                        il.Emit(OpCodes.Call, typeof(Emit).GetMethod("GetLiteralChar", new Type[] { typeof(IJsonReader) }));
+                        il.Emit(OpCodes.Ldarg_0);
+                        il.Emit(OpCodes.Callvirt, typeof(IJsonReader).GetMethod("NextToken", new Type[] { }));
+                    }
 
-                        else if (numericTypes.Contains(m.MemberType))
-                        {
-                            il.Emit(OpCodes.Ldarg_0);
-                            il.Emit(OpCodes.Call, typeof(Emit).GetMethod("GetLiteralNumber", new Type[] { typeof(IJsonReader) }));
+                    else if (numericTypes.Contains(m.MemberType))
+                    {
+                        il.Emit(OpCodes.Ldarg_0);
+                        il.Emit(OpCodes.Call, typeof(Emit).GetMethod("GetLiteralNumber", new Type[] { typeof(IJsonReader) }));
 
-                            // Convert to a string
-                            il.Emit(OpCodes.Call, typeof(CultureInfo).GetProperty("InvariantCulture").GetGetMethod());
-                            il.Emit(OpCodes.Call, m.MemberType.GetMethod("Parse", new Type[] { typeof(string), typeof(IFormatProvider) }));
+                        // Convert to a string
+                        il.Emit(OpCodes.Call, typeof(CultureInfo).GetProperty("InvariantCulture").GetGetMethod());
+                        il.Emit(OpCodes.Call, m.MemberType.GetMethod("Parse", new Type[] { typeof(string), typeof(IFormatProvider) }));
 
-                            il.Emit(OpCodes.Ldarg_0);
-                            il.Emit(OpCodes.Callvirt, typeof(IJsonReader).GetMethod("NextToken", new Type[] { }));
-                        }
+                        il.Emit(OpCodes.Ldarg_0);
+                        il.Emit(OpCodes.Callvirt, typeof(IJsonReader).GetMethod("NextToken", new Type[] { }));
+                    }
 
-                        else
-                        {
-                            il.Emit(OpCodes.Ldarg_0);
-                            il.Emit(OpCodes.Ldtoken, m.MemberType);
-                            il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) }));
-                            il.Emit(OpCodes.Callvirt, typeof(IJsonReader).GetMethod("Parse", new Type[] { typeof(Type) }));
-                            il.Emit(m.MemberType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, m.MemberType);
-                        }
+                    else
+                    {
+                        il.Emit(OpCodes.Ldarg_0);
+                        il.Emit(OpCodes.Ldtoken, m.MemberType);
+                        il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) }));
+                        il.Emit(OpCodes.Callvirt, typeof(IJsonReader).GetMethod("Parse", new Type[] { typeof(Type) }));
+                        il.Emit(m.MemberType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, m.MemberType);
+                    }
 
-                        if (pi != null)
-                        {
-                            il.Emit(OpCodes.Callvirt, pi.GetSetMethod());
-                        }
+                    if (pi != null)
+                    {
+                        il.Emit(OpCodes.Callvirt, pi.GetSetMethod());
+                    }
 
-                        var fi = m.Member as FieldInfo;
-                        if (fi != null)
-                        {
-                            il.Emit(OpCodes.Stfld, fi);
-                        }
+                    var fi = m.Member as FieldInfo;
+                    if (fi != null)
+                    {
+                        il.Emit(OpCodes.Stfld, fi);
+                    }
 
-                        // Cast/unbox the target object and store in local variable
-                        /*
-                        var locTypedObj = il.DeclareLocal(type);
-                        il.Emit(OpCodes.Ldarg_1);
-                        il.Emit(type.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, type);
-                        il.Emit(OpCodes.Stloc, locTypedObj);
+                    // Cast/unbox the target object and store in local variable
+                    /*
+                    var locTypedObj = il.DeclareLocal(type);
+                    il.Emit(OpCodes.Ldarg_1);
+                    il.Emit(type.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, type);
+                    il.Emit(OpCodes.Stloc, locTypedObj);
 
-                        // Get Invariant CultureInfo
-                        var locInvariant = il.DeclareLocal(typeof(IFormatProvider));
-                        il.Emit(OpCodes.Call, typeof(CultureInfo).GetProperty("InvariantCulture").GetGetMethod());
-                        il.Emit(OpCodes.Stloc, locInvariant);
-                         */
+                    // Get Invariant CultureInfo
+                    var locInvariant = il.DeclareLocal(typeof(IFormatProvider));
+                    il.Emit(OpCodes.Call, typeof(CultureInfo).GetProperty("InvariantCulture").GetGetMethod());
+                    il.Emit(OpCodes.Stloc, locInvariant);
+                        */
 
-                        il.Emit(OpCodes.Ret);
+                    il.Emit(OpCodes.Ret);
 
-                        // Store the handler in map
-                        setters.Add(m.JsonKey, (Action<IJsonReader, object>)method.CreateDelegate(typeof(Action<IJsonReader, object>)));
-                    }
-                }
-                catch (Exception x)
-                {
-                    int y = 3;
+                    // Store the handler in map
+                    setters.Add(m.JsonKey, (Action<IJsonReader, object>)method.CreateDelegate(typeof(Action<IJsonReader, object>)));
                 }
 
 

+ 1 - 1
TestCases/Program.cs

@@ -16,7 +16,7 @@ namespace TestCases
 
             var str = p.field.ToString();
 
-            PetaJson.JsonEmit.Init();
+            //PetaJson.JsonEmit.Init();
             PetaTest.Runner.RunMain(args);
         }
     }