至少在Java中,代理模式有很多开销-我不记得确切的数字,但是当包装微小的方法时,代理花费的时间是包装方法的50倍。例如,这就是为什么java.awt.image.BufferedImage.setRGBgetRGB真的很慢的原因。大约有三个代理包裹了实际的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/

10-09 01:52