2010-09-03 11 views
9

Stavo leggendo questa pagina - http://deaduseful.com/blog/posts/50-php-optimisation-tips-revisitedPHP - Zend dire evitare i metodi magici?

E una delle raccomandazioni era quello di evitare l'uso di metodi magici, citato da uno Zend prestazioni PDF che non fornisce alcuna ragione per la sua raccomandazione per evitarli.

Dopo qualche ricerca su Google (e finire qui per una domanda non correlata) mi sono chiesto se qualcuno avesse qualche raccomandazione su quel fronte?

Io uso __get() molto nel mio codice, in genere per salvare variabili che non sempre utilizzo, ad es.

io possa avere una tabella con nome, disc, category_id, time_added

mio get sarebbe simile a questa:

 
public function __get($name) { 
    switch($name) { 
     case 'name': 
     case 'desc': 
     case 'category': 
     case 'time_added': 
      $result = do_mysql_query(); 
      $this->name = $result['name']; 
      $this->desc = $result['desc']; 
      $this->category = $result['category']; 
      $this->time_added = $result['time_added']; 
      return $this->{$name}; 
     break; 
     default: 
      throw Exception("Attempted to access non existant or private property - ".$name); 
    } 
} 

Questo mi sembra un ottimo modo per fare le cose come ho sempre e solo ottenere qualcosa dal database se è necessario e posso riconfermare cose come $ article-> time_added piuttosto che armeggiare con array.

Questo potrebbe essere considerato una cattiva pratica e un carico aggiuntivo sul server?

Spesso estenderò le classi con metodi magici e farò qualcosa del genere se la classe figlio non corrisponde a qualcosa in un get.

 
public function __get($name) { 
    switch($name) { 
     case 'name': 
     case 'desc': 
     case 'category': 
     case 'time_added': 
      $result = do_mysql_query(); 
      $this->name = $result['name']; 
      $this->desc = $result['desc']; 
      $this->category = $result['category']; 
      $this->time_added = $result['time_added']; 
      return $this->{$name}; 
     break; 
     default: 
      return parent::__get($name); 
    } 
} 

Sarebbe una cattiva pratica e un male per le prestazioni? Il numero massimo di livelli che ho quando si estendono i metodi magici è tre.

+0

possibile duplicato del [/ __/__ set domande di prestazioni chiamata __get con PHP] (http://stackoverflow.com/questions/3330852/get- set-call-performance-questions-with-php) – Gordon

risposta

15

È vero, sono più lenti ... ma la differenza è così piccola che la velocità rispetto al codice è un fattore. Vale la pena preoccuparsi della differenza per uno sviluppo e una manutenzione più rapidi?

Vedi magic benchmarks per le statistiche

+17

+1: non puoi sopravvalutare questo sentimento. Ricorda, "L'ottimizzazione prematura è la radice di tutti i mali" ... Se passi tutto il tuo tempo a preoccuparti delle minime differenze di velocità, non otterrai mai nulla. Costruiscilo come fa per te, quindi ** se ** hai problemi, refactoring da lì. Ma il più grande miglioramento delle prestazioni che si può fare è il passaggio da uno stato non lavorativo a uno operativo. Tutto il resto impallidisce nel confronto ... – ircmaxell

+1

Cheers il link sia davvero utile e il tuo punto è molto vero, è molto difficile non rimanere intrappolato nel volere codice prefetto e non rilasciare mai nulla di tutto questo: D – Rob

+4

Il codice mantenibile IMHO è BENE altro importante del codice ad alte prestazioni. Pensaci. È più economico lanciare più hardware a un problema piuttosto che lanciare più sviluppatori su di esso. Questo è uno dei motivi per cui PHP è così popolare ... Ora, c'è sempre un compromesso, quindi non sto raccomandando di ignorare le prestazioni, ma non provare a micro-ottimizzare se non sai se esiste un problema .. – ircmaxell

1

considerare l'utilizzo di array accessors.

class Record implements ArrayAccess { 

    /** 
    * @see ArrayAccess::offsetExists() 
    * 
    * @param offset $offset 
    */ 
    public function offsetExists($offset) { 

    } 

    /** 
    * @see ArrayAccess::offsetGet() 
    * 
    * @param offset $offset 
    */ 
    public function offsetGet($offset) { 
     //fetch and cache $result 

     return $result[$offset]; 
    } 

    /** 
    * @see ArrayAccess::offsetSet() 
    * 
    * @param offset $offset 
    * @param value $value 
    */ 
    public function offsetSet($offset, $value) { 

    } 

    /** 
    * @see ArrayAccess::offsetUnset() 
    * 
    * @param offset $offset 
    */ 
    public function offsetUnset($offset) { 

    } 
+2

E questo è diverso come? Stai solo scambiando quattro metodi magici per altri quattro metodi magici ... – ircmaxell

+0

@ircmaxell I metodi di interfaccia non sono metodi magici. Anche se non riesco a eseguire il backup con i numeri, ritengo che funzioneranno più rapidamente rispetto a quelli basati sugli intercettori – Gordon

+0

@Gordon: è più lento, controlla il collegamento nella risposta sopra. E sì, anche se non è un "metodo magico" in senso stretto, è magico nel senso che l'interfaccia abilita la funzionalità magica (la capacità di usare le funzioni fondamentali e i costrutti del linguaggio sull'oggetto) ... – ircmaxell

1

Ho fatto alcuni test con metodi magici PHP e operazioni nativo get/set (su una proprietà pubblica)

I risultati:

metodi magici sono molto più lento di accesso nativo. MA il tempo di accesso è ancora così piccolo, che non farà la differenza nel 99,9% di tutti i casi.

Anche se si fa 1 milione di metodo magico accede all'interno di una richiesta, ancora vogliono solo circa 0,1 secondi ...


"Sola lettura" significa accesso tramite metodi magici. L'immagine mostra i risultati di PHP 5.5.9 e PHP 7.0.

benchmark results

Ecco lo script di riferimento: https://github.com/stracker-phil/php-benchmark/blob/master/benchmark.php

Problemi correlati