至少在Java中,代理模式有很多开销-我不记得确切的数字,但是当包装微小的方法时,代理花费的时间是包装方法的50倍。例如,这就是为什么java.awt.image.BufferedImage.setRGB
&getRGB
真的很慢的原因。大约有三个代理包裹了实际的byte[]
。
为什么要50次?为什么代理不只是将时间加倍?
编辑:=(
正如SO的通常情况一样,我得到了一堆答案,告诉我我的问题是错误的。不是。签出BufferedImage或其他一些真正的代理模式,而不是那些微基准。实际上,如果您必须对BufferedImage进行很多像素操作并且知道其结构,则可以通过手动撤消代理来实现上述极大的加速。参见this answer。
哦,我的来源是here's,是50倍。正如文章所详细介绍的那样,当代理包装很长时间时,代理并没有受到明显的惩罚,但是如果您包装的是一个小方法,则代理确实会带来很大的痛苦。
最佳答案
我不知道“ 50倍”数字来自何处,但这是很可疑的。可能是某个特定的代理要比其代理的运行明显慢,这取决于它们各自的工作,但是要概括地说“代理模式太慢”是要采取非常戏剧性和高度质疑的态度逻辑上的飞跃。
尝试这个:Thingy.java
:
public class Thingy
{
public int foo(int param1, int param2)
{
return param2 - param1;
}
}
ThingyProxy.java
:public class ThingyProxy
{
Thingy thingy;
public ThingyProxy()
{
this.thingy = new Thingy();
}
public int foo(int param1, int param2)
{
return this.thingy.foo(param1, param2);
}
}
WithoutProxy.java
:public class WithoutProxy
{
public static final void main(String[] args)
{
Thingy t;
int sum;
int counter;
int loops;
sum = 0;
t = new Thingy();
for (loops = 0; loops < 300000000; ++loops) {
sum = 0;
for (counter = 0; counter < 100000000; ++counter) {
sum += t.foo(1, 2);
}
if (sum != 100000000) {
System.out.println("ERROR");
return;
}
}
System.exit(0);
}
}
WithProxy.java
:public class WithProxy
{
public static final void main(String[] args)
{
ThingyProxy t;
int sum;
int counter;
int loops;
sum = 0;
t = new ThingyProxy();
for (loops = 0; loops < 300000000; ++loops) {
sum = 0;
for (counter = 0; counter < 100000000; ++counter) {
sum += t.foo(1, 2);
}
if (sum != 100000000) {
System.out.println("ERROR");
return;
}
}
System.exit(0);
}
}
我的机器上的简单试验:
$ time java WithoutProxy
真正的0m0.894s
用户0m0.900s
sys 0m0.000s
$时间java WithProxy
真正的0m0.934s
用户0m0.940s
sys 0m0.000s
$ time java WithoutProxy
真正的0m0.883s
用户0m0.850s
sys 0m0.040s
$时间java WithProxy
真正的0m0.937s
用户0m0.920s
sys 0分0.030秒
$ time java WithoutProxy
真正的0m0.898s
用户0m0.880s
sys 0分0.030秒
$时间java WithProxy
真正的0m0.936s
用户0m0.950s
sys 0m0.000s
慢一点?是。慢50倍?没有。
现在,众所周知,对JVM进行计时非常困难,并且像上面这样的简单实验必定令人怀疑。但我认为可能会出现50倍的差异。
编辑:我应该提到上面的循环数量非常少,像这样:
真实的0m0.058s
用户0m0.040s
sys 0m0.020s
...使您可以了解环境中VM的启动时间。例如,上述计时并非主要是VM启动,实际执行时间仅相差一微秒,而是主要是执行时间。
关于java - 为什么代理模式这么慢?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5927605/