参考了微软的realproxy设计模式,使用相同的IMessage结构,重写了整个proxy。
使用了emit技术,性能得到了极大提升。
模仿旧的pojo代码,得到:
代码
class
MyProxy
<
T
>
: DynamicProxy
{
Dictionary
<
string
,
object
>
dict
=
new
Dictionary
<
string
,
object
>
();
public
MyProxy()
:
base
(
typeof
(T))
{
}
public
T Value
{
get
{
return
(T)
base
.GetTransparentProxy();
}
}
public
override
IDynamicMethodReturnMessage Invoke(IDynamicMethodCallMessage msg)
{
string
methodname
=
msg.MethodInfo.Name.Trim().ToUpper();
if
(methodname.StartsWith(
"
GET_
"
))
return
InvokeGetter(msg);
if
(methodname.StartsWith(
"
SET_
"
))
return
InvokeSetter(msg);
return
base
.CreateReturnMessage(
new
Exception(
"
only support property.
"
), msg);
}
private
IDynamicMethodReturnMessage InvokeGetter(IDynamicMethodCallMessage methodCall)
{
IDummyMethodInfo method
=
methodCall.MethodInfo;
string
invokeid
=
GetInvokeMessageId(method);
if
(dict.ContainsKey(invokeid))
{
return
base
.CreateReturnMessage(dict[invokeid], methodCall);
}
if
(method.ReturnType.PropertyType
==
DotNetPropertyType.Enum)
{
return
base
.CreateReturnMessage(
0
, methodCall);
}
switch
(Pixysoft.Tools.ParserHelper.GetDataTypeByTypeName(method.ReturnType.Name))
{
case
DotNetDataType.Boolean:
{
return
base
.CreateReturnMessage(
false
, methodCall);
}
case
DotNetDataType.Byte:
{
return
base
.CreateReturnMessage(
byte
.MinValue, methodCall);
}
case
DotNetDataType.Char:
{
return
base
.CreateReturnMessage(
char
.MinValue, methodCall);
}
case
DotNetDataType.DateTime:
{
return
base
.CreateReturnMessage(DateTime.MinValue, methodCall);
}
case
DotNetDataType.Decimal:
{
return
base
.CreateReturnMessage(
decimal
.MinValue, methodCall);
}
case
DotNetDataType.Double:
{
return
base
.CreateReturnMessage(
double
.MinValue, methodCall);
}
case
DotNetDataType.Int32:
{
return
base
.CreateReturnMessage(
int
.MinValue, methodCall);
}
case
DotNetDataType.Int64:
{
return
base
.CreateReturnMessage(Int32.MinValue, methodCall);
}
case
DotNetDataType.Single:
{
return
base
.CreateReturnMessage(Single.MinValue, methodCall);
}
case
DotNetDataType.String:
case
DotNetDataType.UNKNOWN:
default
:
{
return
base
.CreateReturnMessage(
null
, methodCall);
}
}
}
private
IDynamicMethodReturnMessage InvokeSetter(IDynamicMethodCallMessage methodCall)
{
if
(methodCall.InArgCount
==
0
)
return
base
.CreateReturnMessage(
null
, methodCall);
string
invokeid
=
GetInvokeMessageId(methodCall.MethodInfo);
if
(dict.ContainsKey(invokeid))
dict.Remove(invokeid);
dict.Add(invokeid, methodCall.InArgs[
0
]);
return
base
.CreateReturnMessage(
null
, methodCall);
}
private
string
GetInvokeMessageId(IDummyMethodInfo method)
{
StringBuilder builder
=
new
StringBuilder();
builder.Append(method.Name.Substring(
4
));
builder.Append(method.DeclaringType.FullName);
//
return builder.ToString();
return
Pixysoft.Security.MD5.GetMD5(builder.ToString());
}
}
public
interface
IproxyWithProperty
{
string
Name {
set
;
get
;}
}
测试代码如下:
代码
//
performance
public
void
test002()
{
IproxyWithProperty pojo
=
Pixysoft.Tools.PojoHelper.GetPojo
<
IproxyWithProperty
>
();
IproxyWithProperty proxy
=
new
MyProxy
<
IproxyWithProperty
>
().Value;
Pixysoft.Tools.CodeTimer.Initialize();
Pixysoft.Tools.CodeTimer.Time(
"
pojo
"
,
100000
,
delegate
()
{
pojo.Name
=
"
123
"
;
object
name
=
pojo.Name;
});
Pixysoft.Tools.CodeTimer.Time(
"
proxy
"
,
100000
,
delegate
()
{
proxy.Name
=
"
123
"
;
object
name
=
proxy.Name;
});
}
测试结果如下:
------ Test started: Assembly: Pixysoft.Framework.Reflection.dll ------
pojo
Time Elapsed: 7,997ms
CPU time: 7,796,875,000ns
Gen 0: 760
Gen 1: 0
Gen 2: 0
proxy
Time Elapsed: 5,651ms
CPU time: 5,484,375,000ns
Gen 0: 398
Gen 1: 0
Gen 2: 0
1 passed, 0 failed, 0 skipped, took 13.77 seconds (Ad hoc).
性能提高了1.415倍。
如果把初始化proxy的代码放入循环,得到结果:
------ Test started: Assembly: Pixysoft.Framework.Reflection.dll ------
pojo
Time Elapsed: 8,569ms
CPU time: 8,015,625,000ns
Gen 0: 800
Gen 1: 0
Gen 2: 0
proxy
Time Elapsed: 6,263ms
CPU time: 5,843,750,000ns
Gen 0: 475
Gen 1: 0
Gen 2: 0
性能提高了1.368倍。
可以看出,微软的Realproxy本质上并不弱。 内部实现应该使用了类似emit的技术了。。。
因此,一天的努力几乎有点白费了。。。竟然没有提高一个数量级。。。
1 passed, 0 failed, 0 skipped, took 14.92 seconds (Ad hoc).