代码改变世界

C#简单快速的json组件fastJSON

  zhoujie  阅读(16946)  评论(22编辑  收藏  举报

JSON数据格式简洁,用于数据的持久化和对象传输很实用。最近在做一个Razor代码生成器,需要把数据库的表和列的信息修改后保存下来,想到用JSON序列化对象并保存,需要时再反序列化成对象会简单一些。codeplex上发现了fastJSON项目,好像很不错的样子。这里是作者做的性能测试:

 

项目和详细的性能测试地址:http://www.codeproject.com/Articles/159450/fastJSON

代码调用

复制代码
namespace test
{

    class Program
    {
        static void Main(string[] args)
        {
            var zoo1 = new zoo();

            zoo1.animals = new List<animal>();
            zoo1.animals.Add(new cat() { Name = "hello kitty", legs = 4 });
            zoo1.animals.Add(new dog() { Name = "dog1", tail = true });
            string json= fastJSON.JSON.Instance.ToJSON(zoo1); //序列化
            var z = fastJSON.JSON.Instance.ToObject<zoo>(json); //反序列化

            Console.WriteLine(z.animals[0].Name);
            Console.Read();
        }
    }

    public class animal { public string Name { get; set; } }
    public class cat : animal { public int legs { get; set; } }
    public class dog : animal { public bool tail { get; set; } }
    public class zoo { public List<animal> animals { get; set; } 
}
复制代码

基本的调用就是这么简单! 需要注意的是要反序列化的类好像必须声明为public的。

快速的秘密

 大体浏览了一下代码,发现之所以快速的原因是作者利用反射时Emit了大量的IL代码:

复制代码
internal object FastCreateInstance(Type objtype)

        {
            try
            {
                CreateObject c = null;
                if (_constrcache.TryGetValue(objtype, out c))
                {
                    return c();
                }
                else
                {
                    if (objtype.IsClass) 
                    {
                        DynamicMethod dynMethod = new DynamicMethod("_", objtype, null);
                        ILGenerator ilGen = dynMethod.GetILGenerator();
                        ilGen.Emit(OpCodes.Newobj, objtype.GetConstructor(Type.EmptyTypes));
                        ilGen.Emit(OpCodes.Ret);
                        c = (CreateObject)dynMethod.CreateDelegate(typeof(CreateObject));
                        _constrcache.Add(objtype, c);
                    }
                    else // structs
                    {     
                        DynamicMethod dynMethod = new DynamicMethod("_",
                            MethodAttributes.Public | MethodAttributes.Static,
                            CallingConventions.Standard,
                            typeof(object),
                            null,
                            objtype, false);
                        ILGenerator ilGen = dynMethod.GetILGenerator();
                        var lv = ilGen.DeclareLocal(objtype);
                        ilGen.Emit(OpCodes.Ldloca_S, lv);
                        ilGen.Emit(OpCodes.Initobj, objtype);
                        ilGen.Emit(OpCodes.Ldloc_0);
                        ilGen.Emit(OpCodes.Box, objtype);
                        ilGen.Emit(OpCodes.Ret);
                        c = (CreateObject)dynMethod.CreateDelegate(typeof(CreateObject));
                        _constrcache.Add(objtype, c);
                    }
                    return c();
                }
            }
            catch (Exception exc)
            {
                throw new Exception(string.Format("Failed to fast create instance for type '{0}' from assemebly '{1}'",
                    objtype.FullName, objtype.AssemblyQualifiedName), exc);
            }
        }
复制代码
编辑推荐:
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
点击右上角即可分享
微信分享提示