通过之前2篇文章的介绍,大家一定发现了,动态编译后的对象只能通过反射调用,但是反射往往是一个程序性能的瓶颈,这个真的无法突破么?答案当然是否定的,接下来就我就来说说怎么才能,挖掘动态编译的潜力。

  • 一点废话

我刚来博客园才1星期左右,昨天才弄懂怎么发表到首页,先说声抱歉了,昨天的文章有几个地方贴的源码居然少了几个字符,有点莫名其妙,也难怪有人不能运行了,虽然是小错误,但是如果认真检查的话也是可以避免的,这是我的失误。

还有一点,这个《玩转动态编译》是一个系列的,虽然没有大纲,不知道会写到几,但是内容一定是循序渐进的,所以如果你看到了不合理的地方,请不要惊讶,可能我只是为了更好理解,也许下一篇就会把这个地方重构的。

回复上一篇中的博友 飘的移

引用我只想:说这个效率实在太慢了,楼主什么时候能做到接近FastJson或者Newton.Json的速度就牛叉了

FastJson是Java的,我测试不了,但就Newtonsoft.Json的效率来说超过他还是可以的,所以在这个系列没有over之前耐心期待吧。。。。(这个算广告吗)

  • 书归正传,话转正题

通过之前2篇文章的介绍,大家一定发现了,动态编译后的对象只能通过反射调用,但是反射往往是一个程序性能的瓶颈,这个真的无法突破么?答案当然是否定的。

那怎么才能抛弃反射呢?

仔细看之前的《玩转动态编译》大家可以发现,之前2个栗子编译的都是静态方法。
回到昨天的栗子中,被静态编译的User解析类

using blqw;
using System;
using System.Collections;
using System.Text;

public class _336090f4e7724d2585b07e79210decb4
{
    public static string a(User obj)
    {
        return new StringBuilder().Append("{\"UID\":")
            .Append(Json.Converter2.FromGuid((System.Guid)obj.UID))
            .Append(",\"Name\":")
            .Append(Json.Converter2.FromString((System.String)obj.Name))
            .Append(",\"Birthday\":")
            .Append(Json.Converter2.FromDateTime((System.DateTime)obj.Birthday))
            .Append(",\"Sex\":")
            .Append(Json.Converter2.FromEnum((Enum)obj.Sex))
            .Append(",\"IsDeleted\":")
            .Append(Json.Converter2.FromBoolean((System.Boolean)obj.IsDeleted))
            .Append(",\"LoginHistory\":")
            .Append(Json.Converter2.FromArray(((IEnumerable)obj.LoginHistory).GetEnumerator()))
            .Append(",\"Info\":")
            .Append(Json.ToJson_2(obj.Info))
            .Append("}").ToString();
    }
} 

ps:其实回车都是我刚刚加上去的,难道我会乱说?

编译静态的方法,只是为了在反射调用Invoke的时候不要传入实例对象,就像这样

var code = CreateCode(type);//获得代码
var ass = DynamicCompile_1.CompileAssembly(code, typeof(Json), typeof(StringBuilder), typeof(IDictionary), typeof(Enum), typeof(IEnumerable), typeof(IEnumerator));//编译
var met = ass.GetTypes()[0].GetMethods()[0];//反射唯一的一个对象中的唯一的一个方法
return (string)met.Invoke(null, new object[] { user });//执行方法,等到返回值

程序中,我们可以缓存最后的met对象,可以防止反复的编译。不过就算是这样,每次调用met对象的时候依然是反射调用(Invoke)

是静态方法的话就意味着必须要使用反射,静态只能通过 类名.方法名 来调用,而动态编译的类名是在程序运行时决定的。。。。

  • 思考?

那么是否意味着实例方法就可以呢?

把上面的动态代码改一下

using blqw;
using System;
using System.Collections;
using System.Text;

public class _336090f4e7724d2585b07e79210decb4 : blqw.IGetString
{
    public string GetString(object o)
    {
        User obj = (User)o;
        return new StringBuilder().Append("{\"UID\":")
            .Append(Json.Converter2.FromGuid((System.Guid)obj.UID))
            .Append(",\"Name\":")
            .Append(Json.Converter2.FromString((System.String)obj.Name))
            .Append(",\"Birthday\":")
            .Append(Json.Converter2.FromDateTime((System.DateTime)obj.Birthday))
            .Append(",\"Sex\":")
            .Append(Json.Converter2.FromEnum((System.Enum)obj.Sex))
            .Append(",\"IsDeleted\":")
            .Append(Json.Converter2.FromBoolean((System.Boolean)obj.IsDeleted))
            .Append(",\"LoginHistory\":")
            .Append(Json.Converter2.FromArray(((IEnumerable)obj.LoginHistory).GetEnumerator()))
            .Append(",\"Info\":")
            .Append(Json.ToJson_2(obj.Info))
            .Append("}").ToString();
    }
}

看有那些地方改变?

1,实现了IGetString的接口

namespace blqw
{
    public interface IGetString
    {
        string GetString(object obj);
    }
}
IGetString 接口

相关文章:

  • 2022-12-23
  • 2021-07-30
  • 2021-11-10
  • 2021-12-30
  • 2021-09-12
  • 2021-05-21
  • 2021-10-13
猜你喜欢
  • 2021-08-10
  • 2021-06-25
  • 2021-05-20
  • 2021-11-11
  • 2021-11-30
相关资源
相似解决方案