new的原罪
一直以为在开发阶段能够直接调用的,速度而言一定是最优秀的,因为总比后期通过反射之类来调用来得快吧.
下面请看一个SB的例子,重新编译以后,这个类在创建100,000,000实体时居然耗费了16秒的时间:
internal class CreateWithNew<T> : EntityCreator<T> where T : new()
{
public override T Create()
{
return new T();
}
}//此SB相当荣幸的以为这个调用速度一定是最快的,怎么的也是编译级别的吧
奶奶的,居然还不如之前的解决方案:(创建100,000,000实体约4秒)
/// <summary>
/// 根据参数的类型,创建一个句柄,这个句柄可以根据对应的参数列表创建指定的实例
/// </summary>
/// <param name="parameterTypes">参数类型列表</param>
/// <returns>用于创建实例的句柄</returns>
private static Func<object[], TType> GenerateCreateInstanceHandler(Type[] parameterTypes)
{
Type type = typeof(TType);
if (type.IsSealed && type.IsAbstract)
{
throw new NotSupportedException(string.Concat("不支持用于创建静态类型的实例:", Reflector.GetTypeName(type)));
}
if (type.IsArray || type.IsEnum || type.IsGenericTypeDefinition || type.IsGenericParameter)
{
throw new NotSupportedException(string.Concat("不支持用于创建数组,枚举,泛型定义,泛型参数的实例:", Reflector.GetTypeName(type)));
}
if (type.IsNotPublic && (type.IsInterface || type.IsAbstract))
{
throw new NotSupportedException(string.Concat("不支持用于创建非公开的接口及抽象类型的实例:", Reflector.GetTypeName(type)));
}
//if (type.IsAbstract || type.IsInterface)
//{
// TypeFactory factory = TypeFactory.Create(type);
// factory.ImplementBase();
// type = factory.CreateType();
//}
ConstructorInfo constructor = Reflector.GetConstructor(type, parameterTypes);
DynamicMethodFactory<Func<object[], TType>> method = DynamicMethodFactory<Func<object[], TType>>.Create("CreateInstance"); /*
* If found match constructor, then invoke it.
* Else if found any constructor, use default parameters.
*/ MethodInfo convert =
new Func<object[], int, object>(GetParameter<object>).Method.GetGenericMethodDefinition(); if (constructor != null)
{
#region Use a match constructor to create a new instance ParameterInfo[] parameters = constructor.GetParameters();
if (type.IsClass)
{
int len = parameterTypes.Length;
for (int i = 0; i < len; i++)
{
ParameterInfo p = parameters[i];
method.LoadArg(0).Load(i);
method.Call(convert.MakeGenericMethod(p.ParameterType));
}
method.New(constructor).Return();
}
else
{
LocalBuilder result = method.Declare(type);
method.LoadVarAddr(result);
int len = parameterTypes.Length;
for (int i = 0; i < len; i++)
{
ParameterInfo p = parameters[i];
method.LoadArg(0).Load(i);
method.Call(convert.MakeGenericMethod(p.ParameterType));
}
method.Call(constructor);
method.LoadVar(result).Return();
} #endregion
}
else
{
method.LoadDefault<TType>().Return();
}
return method.Delegation;
}
奶奶的 ,抽象类居然被委托打败了,我很想学着穿越小说里面的SB配角大喊一声:怎么可能
于是开始分析,我X他娘的,居然发现NEW()被解释成了这个,他妈的这还不如直接反射算了
System.Activator.CreateInstance()
于是果断修改成这样:
if (con.IsPublic && type.IsPublic)
{
Type parent = typeof (EntityCreator<T>);
TypeFactory factory = TypeFactory.Create(parent);
factory.DefineOverride(parent.GetMethod("Create"), m =>
{
m.New(con).Return();
});
Type creator = factory.CreateType();
Createor = Reflector.CreateInstanceAs<EntityCreator<T>>(creator);
}
else
{
Createor = new CreateWithPrivateNew<T>();
}
接下来表现如何?
2.6秒!!!
OK,我心里平衡了.
new的原罪的更多相关文章
- [react] 细数 React 的原罪
Props & onChange 的原罪 .「props & onChange 接口规范」它不是一个典型的「程序接口规范」. 当你拿到一个可视组件的 ref,却没有类似 setProp ...
- [转帖][分享] 关于系统DIY--by 原罪
http://wuyou.net/forum.php?mod=viewthread&tid=399277&extra=page%3D1 前几天我发了一个帖子<Windows组件w ...
- Python踩坑之旅其二裸用os.system的原罪
目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4.1 技术关键字 1.5 填坑总结 2. 前坑回顾 2.1 Linux中, 子进程拷贝父进程哪些信息 2.2 Agent常驻进程选择& ...
- <把时间当做朋友>读书笔记
这本书我早就看过,还想再来一遍 开始这一行动是看李萌在朋友圈晒101计划,每天健身,读书半小时之类的,我也想做点啥,那就每天睡前读书半小时吧,怎么坚持下去呢? 我不想晒到朋友圈里,那就晒给玉玉看吧, ...
- codeforces 731C(DFS)
题目链接:http://codeforces.com/contest/731/problem/C 题意:有n只袜子(1~n),k种颜色(1~k),在m天中,左脚穿下标为l,右脚穿下标为r的袜子,问最少 ...
- Java学习笔记:控制反转
控制反转(Ioc)模式(又称DI:Dependency Injection)就是Inversion of Control,控制反转.在Java开发中,IoC意味着将你设计好的类交给系统去控制,而不是在 ...
- 形象化的spring 依赖注入原理
转. IoC就是Inversion of Control,控制反转.在Java开发中,IoC意味着将你设计好的类交给系统去控制,而不是在你的类内部控制.这称为控制反转. 下面我们以几个例子来说明什 ...
- 【jquery】幻灯片效果
闲着无聊,用Jquery写了一个幻灯片效果. 我这人喜欢造轮子,除了jquery这种有强大开发团队的框架级别JS,其实的一些小程序都是尽量自己写. 一是因为怕出问题了没人问,二是自己写的改起来也方便. ...
- 聊聊JS与设计模式之(工厂Factory)篇------(麦当劳的故事)
一,总体概要 1,笔者浅谈 说起设计模式其实并不是什么很新奇的概念,它也不是基于特定语言所形成的产物,它是基于软件设计原则以及相关的方法论和经过特定时期衍生出的若干解决方案.本文会以一个实例带入大家学 ...
随机推荐
- -[UIKeyboardLayoutStar release]: message sent to deallocated instance 0x7fbe49120000
__NSArrayM objectAtIndex: 取消swizzle 只有debug的时候会报错,发布的时候是好的,所以可以不用改
- Devexpress WidgetView 使用总结
效果图: 1.添加DocumentManager控件 2.Convert to WidgetView 3.添加Document,设定ControlTypeName属性,第5步用到 4.添加StackG ...
- bash:fdisk:command not found
bash:fdisk:command not found [lansir@Red-Hat ~]$ fdisk -l-bash: fdisk: command not found 原因是fdisk不在P ...
- Linux Svn 安装过程及配置
重要的是第一步的安装,第二步配置可能没用,但是没试过,因为服务器上已经安装了第一步. 此处的第二步只为做个记录,说明一下里边的配置文件的用途. 3. 自己实际操作中的的配置记录(参照服务器别人的配置记 ...
- Linux入门学习,开启端口号
之前买了一个阿里云Centos 7服务器,默认开启22端口和80端口,想开启其他端口号如何做 1.开启端口号 [root@localhost ~]# /sbin/iptables -I INPUT - ...
- Python3利用BeautifulSoup4批量抓取站点图片的代码
边学边写代码,记录下来.这段代码用于批量抓取主站下所有子网页中符合特定尺寸要求的的图片文件,支持中断. 原理很简单:使用BeautifulSoup4分析网页,获取网页<a/>和<im ...
- AndroidSQLite多出一个(db.journal文件原因)
今天在Android开发中中将sqlite的数据库创建之后,发现生成的.db文件的旁边 生成了一个大小为0的与数据库文件同名的.db-journal文件,不明白此文件的用途,于是 google了sql ...
- Oracle RMAN 恢复控制文件到指定的路径
Oracle 数据库通过RMAN恢复控制文件到指定的路径 --------------------------------------------------------- 先查询备份集信息,再指定备 ...
- WCF权限控制
前面写了 WCF账户密码认证, 实现了帐号密码认证, 接下来看看如何对方法的细粒度控制, 本文很大程度参考了 WCF安全之基于自定义声明授权策略, 这篇文章对原理讲得比较清楚, 而我这篇文章呢, ...
- 【随笔】js加载
有时候,当发现js操作一个dom的时候,发现dom没有找到,这是由于html没有加载完就开始操作该dom的缘故,所以需要在html文档加载完后再加载js,于是我们可以这么做: js方法:window. ...