Consoletest/Program.cs | 31 ++--
Consoletest/consoletest.csproj | 1 -
Consoletest/dataobjects.cs | 4 +
fastJSON/JSON.cs | 338 ++++++++++++++++++++++++++---------------
fastJSON/JsonParser.cs | 11 +-
fastJSON/JsonSerializer.cs | 28 ++--
fastJSON/fastJSON.csproj | 4 +-
7 files changed, 261 insertions(+), 156 deletions(-)
diff --git a/Consoletest/Program.cs b/Consoletest/Program.cs
index 1911e21..68a8b5e 100644
--- a/Consoletest/Program.cs
+++ b/Consoletest/Program.cs
@@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Data;
+using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
@@ -171,19 +172,21 @@ namespace consoletest
Console.WriteLine();
Console.Write("fastjson deserialize");
colclass c = CreateObject();
+ var stopwatch = new Stopwatch();
for (int pp = 0; pp < tcount; pp++)
{
- DateTime st = DateTime.Now;
colclass deserializedStore;
string jsonText = null;
+ stopwatch.Restart();
jsonText = fastJSON.JSON.Instance.ToJSON(c);
//Console.WriteLine(" size = " + jsonText.Length);
for (int i = 0; i < count; i++)
{
deserializedStore = (colclass)fastJSON.JSON.Instance.ToObject(jsonText);
}
- Console.Write("\t" + DateTime.Now.Subtract(st).TotalMilliseconds);
+ stopwatch.Stop();
+ Console.Write("\t" + stopwatch.ElapsedMilliseconds);
}
}
@@ -192,15 +195,17 @@ namespace consoletest
Console.WriteLine();
Console.Write("fastjson serialize");
colclass c = CreateObject();
+ var stopwatch = new Stopwatch();
for (int pp = 0; pp < tcount; pp++)
{
- DateTime st = DateTime.Now;
string jsonText = null;
+ stopwatch.Restart();
for (int i = 0; i < count; i++)
{
jsonText = fastJSON.JSON.Instance.ToJSON(c);
}
- Console.Write("\t" + DateTime.Now.Subtract(st).TotalMilliseconds);
+ stopwatch.Stop();
+ Console.Write("\t" + stopwatch.ElapsedMilliseconds);
}
}
@@ -209,20 +214,24 @@ namespace consoletest
Console.WriteLine();
Console.Write("bin deserialize");
colclass c = CreateObject();
+ var stopwatch = new Stopwatch();
for (int pp = 0; pp < tcount; pp++)
{
- DateTime st = DateTime.Now;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
+ colclass deserializedStore = null;
+ stopwatch.Restart();
bf.Serialize(ms, c);
- colclass deserializedStore = null;
//Console.WriteLine(" size = " +ms.Length);
for (int i = 0; i < count; i++)
{
+ stopwatch.Stop(); // we stop then resume the stopwatch here so we don't factor in Seek()'s execution
ms.Seek(0L, SeekOrigin.Begin);
+ stopwatch.Start();
deserializedStore = (colclass)bf.Deserialize(ms);
}
- Console.Write("\t" + DateTime.Now.Subtract(st).TotalMilliseconds);
+ stopwatch.Stop();
+ Console.Write("\t" + stopwatch.ElapsedMilliseconds);
}
}
@@ -230,17 +239,21 @@ namespace consoletest
{
Console.Write("\r\nbin serialize");
colclass c = CreateObject();
+ var stopwatch = new Stopwatch();
for (int pp = 0; pp < tcount; pp++)
{
- DateTime st = DateTime.Now;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
+ stopwatch.Restart();
for (int i = 0; i < count; i++)
{
+ stopwatch.Stop(); // we stop then resume the stop watch here so we don't factor in the MemoryStream()'s execution
ms = new MemoryStream();
+ stopwatch.Start();
bf.Serialize(ms, c);
}
- Console.Write("\t" + DateTime.Now.Subtract(st).TotalMilliseconds);
+ stopwatch.Stop();
+ Console.Write("\t" + stopwatch.ElapsedMilliseconds);
}
}
diff --git a/Consoletest/consoletest.csproj b/Consoletest/consoletest.csproj
index 1af547c..9652f6f 100644
--- a/Consoletest/consoletest.csproj
+++ b/Consoletest/consoletest.csproj
@@ -59,7 +59,6 @@
-
diff --git a/Consoletest/dataobjects.cs b/Consoletest/dataobjects.cs
index 8a77c3a..2631a4c 100644
--- a/Consoletest/dataobjects.cs
+++ b/Consoletest/dataobjects.cs
@@ -8,12 +8,14 @@ namespace consoletest
#region [ data objects ]
+ [Serializable]
public class baseclass
{
public string Name { get; set; }
public string Code { get; set; }
}
+ [Serializable]
public class class1 : baseclass
{
public class1() { }
@@ -26,6 +28,7 @@ namespace consoletest
public Guid guid { get; set; }
}
+ [Serializable]
public class class2 : baseclass
{
public class2() { }
@@ -44,6 +47,7 @@ namespace consoletest
Female
}
+ [Serializable]
public class colclass
{
public colclass()
diff --git a/fastJSON/JSON.cs b/fastJSON/JSON.cs
index 452a822..81b1260 100644
--- a/fastJSON/JSON.cs
+++ b/fastJSON/JSON.cs
@@ -68,6 +68,7 @@ namespace fastJSON
public sealed class JSON
{
+ //static JSON() { Console.WriteLine("myPropInfo: {0}", System.Runtime.InteropServices.Marshal.SizeOf(typeof(myPropInfo)).ToString("X8")); }
//public readonly static JSON Instance = new JSON();
[ThreadStatic]
private static JSON _instance;
@@ -229,39 +230,55 @@ namespace fastJSON
#region [ JSON specific reflection ]
+ private enum myPropInfoType
+ {
+ Int,
+ Long,
+ String,
+ Bool,
+ DateTime,
+ Enum,
+ Guid,
+
+ Array,
+ ByteArray,
+ Dictionary,
+ StringDictionary,
+#if !SILVERLIGHT
+ Hashtable,
+ DataSet,
+ DataTable,
+#endif
+#if CUSTOMTYPE
+ Custom,
+#endif
+
+ Unknown,
+ };
+ [Flags]
+ private enum myPropInfoFlags
+ {
+ Filled = 1<<0,
+ CanWrite = 1<<1,
+ Class = 1<<2,
+ ValueType = 1<<3,
+ GenericType = 1<<4,
+ };
private struct myPropInfo
{
- public bool filled;
public Type pt;
public Type bt;
public Type changeType;
- public bool isDictionary;
- public bool isValueType;
- public bool isGenericType;
- public bool isArray;
- public bool isByteArray;
- public bool isGuid;
-#if !SILVERLIGHT
- public bool isDataSet;
- public bool isDataTable;
- public bool isHashtable;
-#endif
- public Reflection.GenericSetter setter;
- public bool isEnum;
- public bool isDateTime;
- public Type[] GenericTypes;
- public bool isInt;
- public bool isLong;
- public bool isString;
- public bool isBool;
- public bool isClass;
- public Reflection.GenericGetter getter;
- public bool isStringDictionary;
- public string Name;
-#if CUSTOMTYPE
- public bool isCustomType;
-#endif
- public bool CanWrite;
+ public Reflection.GenericSetter setter;
+ public Reflection.GenericGetter getter;
+ public Type[] GenericTypes;
+ public string Name;
+ public myPropInfoType Type;
+ public myPropInfoFlags Flags;
+
+ public bool IsClass { get { return (Flags & myPropInfoFlags.Class) != 0; } }
+ public bool IsValueType { get { return (Flags & myPropInfoFlags.ValueType) != 0; } }
+ public bool IsGenericType { get { return (Flags & myPropInfoFlags.GenericType) != 0; } }
}
SafeDictionary> _propertycache = new SafeDictionary>();
@@ -279,7 +296,7 @@ namespace fastJSON
foreach (PropertyInfo p in pr)
{
myPropInfo d = CreateMyProp(p.PropertyType, p.Name);
- d.CanWrite = p.CanWrite;
+ d.Flags |= myPropInfoFlags.CanWrite;
d.setter = Reflection.CreateSetMethod(type, p);
d.getter = Reflection.CreateGetMethod(type, p);
sd.Add(p.Name, d);
@@ -301,44 +318,55 @@ namespace fastJSON
private myPropInfo CreateMyProp(Type t, string name)
{
myPropInfo d = new myPropInfo();
- d.filled = true;
- d.CanWrite = true;
- d.pt = t;
- d.Name = name;
- d.isDictionary = t.Name.Contains("Dictionary");
- if (d.isDictionary)
- d.GenericTypes = t.GetGenericArguments();
- d.isValueType = t.IsValueType;
- d.isGenericType = t.IsGenericType;
- d.isArray = t.IsArray;
- if (d.isArray)
- d.bt = t.GetElementType();
- if (d.isGenericType)
- d.bt = t.GetGenericArguments()[0];
- d.isByteArray = t == typeof(byte[]);
- d.isGuid = (t == typeof(Guid) || t == typeof(Guid?));
+ myPropInfoType d_type = myPropInfoType.Unknown;
+ myPropInfoFlags d_flags = myPropInfoFlags.Filled | myPropInfoFlags.CanWrite;
+
+ if (t == typeof(int) || t == typeof(int?)) d_type = myPropInfoType.Int;
+ else if (t == typeof(long) || t == typeof(long?)) d_type = myPropInfoType.Long;
+ else if (t == typeof(string)) d_type = myPropInfoType.String;
+ else if (t == typeof(bool) || t == typeof(bool?)) d_type = myPropInfoType.Bool;
+ else if (t == typeof(DateTime) || t == typeof(DateTime?)) d_type = myPropInfoType.DateTime;
+ else if (t.IsEnum) d_type = myPropInfoType.Enum;
+ else if (t == typeof(Guid) || t == typeof(Guid?)) d_type = myPropInfoType.Guid;
+ else if (t.IsArray)
+ {
+ d.bt = t.GetElementType();
+ if (t == typeof(byte[]))
+ d_type = myPropInfoType.ByteArray;
+ else
+ d_type = myPropInfoType.Array;
+ }
+ else if (t.Name.Contains("Dictionary"))
+ {
+ d.GenericTypes = t.GetGenericArguments();
+ if(d.GenericTypes.Length > 0 && d.GenericTypes[0] == typeof(string))
+ d_type = myPropInfoType.StringDictionary;
+ else
+ d_type = myPropInfoType.Dictionary;
+ }
#if !SILVERLIGHT
- d.isHashtable = t == typeof(Hashtable);
- d.isDataSet = t == typeof(DataSet);
- d.isDataTable = t == typeof(DataTable);
+ else if (t == typeof(Hashtable)) d_type = myPropInfoType.Hashtable;
+ else if (t == typeof(DataSet)) d_type = myPropInfoType.DataSet;
+ else if (t == typeof(DataTable)) d_type = myPropInfoType.DataTable;
+#endif
+#if CUSTOMTYPE
+ else if (IsTypeRegistered(t)) d_type = myPropInfoType.Custom;
#endif
- d.changeType = GetChangeType(t);
- d.isEnum = t.IsEnum;
- d.isDateTime = t == typeof(DateTime) || t == typeof(DateTime?);
- d.isInt = t == typeof(int) || t == typeof(int?);
- d.isLong = t == typeof(long) || t == typeof(long?);
- d.isString = t == typeof(string);
- d.isBool = t == typeof(bool) || t == typeof(bool?);
- d.isClass = t.IsClass;
+ if (t.IsClass) d_flags |= myPropInfoFlags.Class;
+ if (t.IsValueType) d_flags |= myPropInfoFlags.ValueType;
+ if (t.IsGenericType)
+ {
+ d_flags |= myPropInfoFlags.GenericType;
+ d.bt = t.GetGenericArguments()[0];
+ }
- if (d.isDictionary && d.GenericTypes.Length > 0 && d.GenericTypes[0] == typeof(string))
- d.isStringDictionary = true;
+ d.pt = t;
+ d.Name = name;
+ d.changeType = GetChangeType(t);
+ d.Type = d_type;
+ d.Flags = d_flags;
-#if CUSTOMTYPE
- if (IsTypeRegistered(t))
- d.isCustomType = true;
-#endif
return d;
}
@@ -469,74 +497,59 @@ namespace fastJSON
myPropInfo pi;
if (props.TryGetValue(name, out pi) == false)
continue;
- if (pi.filled && pi.CanWrite)
+ if ((pi.Flags & (myPropInfoFlags.Filled|myPropInfoFlags.CanWrite)) != 0)
{
object v = d[name];
if (v != null)
{
- object oset = null;
-
- if (pi.isInt)
- oset = (int)((long)v);
-#if CUSTOMTYPE
- else if (pi.isCustomType)
- oset = CreateCustom((string)v, pi.pt);
-#endif
- else if (pi.isLong)
- oset = (long)v;
-
- else if (pi.isString)
- oset = (string)v;
-
- else if (pi.isBool)
- oset = (bool)v;
-
- else if (pi.isGenericType && pi.isValueType == false && pi.isDictionary == false && v is List