Что означает «вызов методов напрямую, а не через ссылку»? - PullRequest
4 голосов
/ 18 августа 2011

Я только что просмотрел слайд-шоу от Гранта Скиннера , посвященное повышению производительности ActionScript.Один совет, который он дал, был написан так: «Вызывайте методы напрямую, а не через ссылку».Я не совсем понимаю, что это значит ...

Значит ли это избегать вызова функции для переменной, ссылающейся на объект функции?

var someObjectsDoSomethingMethod:Function = someObj.doSomething;
someObjectsDoSomethingMethod();

Или не создавать функциювызов переменной, ссылающейся на другой объект, который обладает этим методом?

var someObject:Function = someObj;
someObject.doSomething();

Или ...?

Ответы [ 2 ]

1 голос
/ 21 августа 2011

Вы на правильном пути, он говорит, что, если это возможно (особенно для вызовов методов внутри циклов), что самый быстрый способ - вообще не использовать вызов метода (см. Слайд 51), но если вы должны затем попытаться напрямую вызвать метод (слайд 52). Хотя это не всегда практично или желательно, есть некоторые накладные расходы, зависящие от того, как вы вызываете метод и от какого объекта вы вызываете его.

Самое главное, что затворы действительно дороги.

Например:

WithAnonymousFunction.Go(function() { /* Do Work */ });  // Slow
WithReference.Go(new WorkerClass()); // Faster
WithAnonymousReference.Go((new WorkerClass()).doWork); // Faster
WithMethod.Go(); // Even faster!
WithInlinedMthod.Go() // Fastest!

public class WithAnonymousFunction {
    public static function Go(func:Function):void { 
        func();         
    }
}

public class WorkerClass {
    public doWork() { // Do Work }
}

public class WithAnonymousReference {        
    public static function Go(func:Function) {
        func();         
    }
}

public class WithReference {
    public static function Go(cls:WorkerClass) {
        cls.doWork()
    }
}   

public class WithMethod {
    public static function Go() {
        doWork();
    }

    public static function doWork():void { // Do Work }
}

public class WithInlinedMethod {
    public static function Go() {
        // Do Work
    }
}

Одна вещь, в которой я не уверен, это разница в производительности между использованием конкретного класса и интерфейса.

0 голосов
/ 18 августа 2011
var someFunction:Function = function():void{}

будет работать медленнее, чем

public function someFunction():void{}

Является ли различие достаточным, чтобы оно имело большое значение, - это совсем другая история. Я думаю, что есть много смысла в использовании переменных с типом функции в качестве временных обратных вызовов для «событий» (не событий Flash AS3, но общего значения слова «событие»), которые не встречаются один раз в цикле обновления. Даже в цикле обновления эта стратегия на намного более дружественна к производительности, чем при использовании собственной модели диспетчеризации событий Flash (особенно, если вы используете всплывающее окно событий, которое является абсолютной фигурой).

Конечно, он также может ссылаться на Закон Деметры, который является средством инкапсуляции глубоко вложенных отношений типа has-a, так что вам все равно, если doFoo () требует 10 ссылок на объекты и функции звонки под капотом, пока foo сделано. Закон Деметры может очень сильно влиять на производительность, в зависимости от того, насколько глубоким будет стек вызовов при вызове doFoo ().

Что касается вопроса в вашем комментарии, достаточно легко проверить себя. Во флаконе:

// on frame 1
var textField:TextField = new TextField();
this.addChild(textField);

var f:Function = this.stop();
var i:int = 0;
var ilen:int = 100000;

var time:int;

time = getTimer();
for(i = 0 ; i < ilen ; i++){
    f();
}
time = getTimer() - time;
textField.text = "f() :: "+String(time)+"\n";

this.gotoAndStop(2);

// on frame 2

var mc:MovieClip = new MovieClip();
time = getTimer();
for(i = 0 ; i < ilen ; i++){
    mc.stop();
}
time = getTimer() - time;
textField.appendText("mc.stop() :: " + String(time));
this.stop();

Я не проверял это, поэтому могут быть синтаксические ошибки. Конечно, вам понадобится и правильный импорт. Это должно быть логично, однако.

Обязательно проверьте это в браузере, а не только в проигрывателе отладки или проигрывателе предварительного просмотра. Ваш плагин для браузера будет иметь более высокие показатели производительности, а также, скорее всего, будет тем, что имеет конечный пользователь на своем компьютере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...