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,笔者浅谈 说起设计模式其实并不是什么很新奇的概念,它也不是基于特定语言所形成的产物,它是基于软件设计原则以及相关的方法论和经过特定时期衍生出的若干解决方案.本文会以一个实例带入大家学 ...
随机推荐
- javax/javaee-api/ Maven依赖
<dependency> <groupId>javax</groupId> <artifactId>javaee-api</artif ...
- Struts框架——(二)Struts原理with登录实例
二. Struts基本工作流程 假设现在有以下情景: 用户正在浏览一个用STRUTS的技术构建的网站主页,主页上有个登陆表单,用户填好登陆名和密码,单击"登陆"按钮,就激活了以下一 ...
- call
-------siwuxie095 call 调用另一个批处理程序或自身程序段,调用完,程序会回到原来 call 的地方继续执行 如果在脚本或批处理文件外使用 call,则不会在命令行起作用 语法 c ...
- The path to the driver executable must be set by the webdriver.gecko.driver system property
报这个错,是因为你使用了selenium3+Firefox.在selenium3中,使用Firefox,需要添加驱动. 您可以从Github上下载驱动程序下载网址- https://github.c ...
- mysql中的游标使用案例
DELIMITER $$ DROP PROCEDURE IF EXISTS `curTest`$$ CREATE PROCEDURE curTest(IN _myId INT) BEGIN DECLA ...
- NGUI 屏幕自适应(初始设定宽高800x480只支持比其大的屏幕)
自适应讲解部分可以参考以下网址:http://www.xuanyusong.com/archives/2536,下面代码中提到的AdaptiveManualHeight()函数就是参考该文章的. 下面 ...
- JavaWeb 学习004-增删改查的编写
完成了grade,student模块的 数据库连接部分,还需要不断重复这个过程,熟练掌握JDBC的编写. 在不断编写的过程中,加深理解代码. 下一步 1.biz层面的知识内容 2.还有就是登陆成功后跳 ...
- 说一说line-height
line-height这个样式相信大家一定不会陌生,我们经常用它来让文本上下居中,这样做一般不出出现什么问题,但是如果对这个属性不是很熟悉的话,可能会踩到一些坑,今天亲自去试验了一下,并总结了一下li ...
- 寻找子域名的IP段
校网网络安全检测,第一步,我们做的工作是找出学校所有的IP段. 当然,期间我们可以利用软件帮助我们扫描,但是一款软件往往是不够的,因为它全面,所以我们用了IISPutScanner,subDomai ...
- sql server 还原数据库后,删除用户,提示数据库主体在该数据库中拥有架构,无法删除解决方法
将另一台服务器上的数据库备份文件,在现在用的这台服务器上还原之后,再创建相同的用户名,提示用户已存在 想将之前的用户先删除掉,却提示“数据库主体在该数据库中拥有架构,无法删除解决方法” 在网上找到方法 ...