Wydajność dostępu do pól klasy

Przedstawiona teoria dotyczy wielu języków interpretowanych… m.in PHP i Python.

Jeżeli posiadasz złożone klasy zawierające wiele pól (czy to statycznych i dynamiczny) i w swoich metodach wykorzystujesz je dosyć często, np w ten sposób:

[php]
public static function fetchAll($query = null, $args = array())
{
$sql = 'SELECT ’ . static::$_columns . ’ FROM ’ . static::$_table . (isset(static::$_joinLeft[static::$_table]) ? static::$_joinLeft[static::$_table] : null);

if ($query) {
$sql .= ’ WHERE ’ . $query;
}

$collection = array();

if (empty(self::$_selectQuery[static::$_table]) || self::$_selectQuery[static::$_table] != $sql) {
self::$_selectStatement[static::$_table] = Database::getInstance(static::$_database)->prepare($sql);
self::$_selectQuery[static::$_table] = $sql;
}

foreach($args as $k => $v) {
self::$_selectStatement[static::$_table]->bindValue($k+1, $v);
}

self::$_selectStatement[static::$_table]->execute();

// —

return $collection;
}
[/php]

to w takim przypadku system będzie każdorazowo musiał odpytać do pamięci o to pole. Niestety ale tak to działa. Można znacznie przyspieszyć wykonywanie tego kodu poprzez stworzenie lokalnej wartości, tak aby nie było konieczności każdorazowego odwoływania się do klasy. Zrobiłem szybki test w którym stworzyłem 4 klasy:

[php]
class A {

public static $_a = 4;

public function a() {

$a = self::$_a;
$b = self::$_a;
$c = self::$_a;
$d = self::$_a;
$e = self::$_a;
$f = self::$_a;

}
}

class B {

public static $_a = 4;

public function a() {

$local = self::$_a;
$a = $local;
$b = $local;
$c = $local;
$d = $local;
$e = $local;
$f = $local;

}
}

class C {

public $_a = 4;

public function a() {

$a = $this->_a;
$b = $this->_a;
$c = $this->_a;
$d = $this->_a;
$e = $this->_a;
$f = $this->_a;

}
}

class D {

public $_a = 4;

public function a() {

$local = $this->_a;
$a = $local;
$b = $local;
$c = $v;
$d = $v;
$e = $local;
$f = $local;

}
}
[/php]

Jak widać nie robią one nic niesamowitego, ale robią w zasadzie to samo… tylko, że w różny sposób:

Test polegał na utworzeniu instancji i wywołaniu na każdej instancji 1 mln razy metody a()

Wyniki są następujące:

dla Windows

A: static1.1116s
B: static with local0.6764s
C: dynamic0.9799s
D: dynamic with local0.6258s

Jak widać, poprzez utworzenie zwykłej zmiennej, która ma dostęp lokalny uzyskujemy prawie 2x przyspieszenie wykonywania kodu.