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: static | 1.1116s |
B: static with local | 0.6764s |
C: dynamic | 0.9799s |
D: dynamic with local | 0.6258s |
Jak widać, poprzez utworzenie zwykłej zmiennej, która ma dostęp lokalny uzyskujemy prawie 2x przyspieszenie wykonywania kodu.