2010-08-30 17 views
11

Citando PerlMonks: The difference between my and local,¿Cómo es "mi" más rápido que "local" en Perl?

Pero en la vida real, que funciona prácticamente de la misma? Sí. Más o menos Entonces, ¿cuándo deberías usarlos?

Usar mi cuando se puede (que es más rápido que el local) ...

que conoce el léxico vs diferencia de alcance dinámico entre my y local, como se discutió en this SO thread, pero no estoy seguro por qué my es "más rápido".

¿Qué queremos decir exactamente cuando decimos que una variable my es más rápida que una variable local en Perl?

+1

Sea un héroe * local * - intente leer el código * my *. –

+12

No use local vs. my porque uno es más rápido que el otro; use lo que sea más correcto para lo que quiere lograr (generalmente mi). – ysth

+1

En otras palabras: no solo cuente el tiempo que demora ejecutar un programa, sobre todo, cuente el tiempo que le toma a un programador depurarlo y corregirlo. El programador es mucho más costoso que la computadora que ejecuta el programa. – reinierpost

Respuesta

19

El uso de local en una variable significa que su estado anterior debe ser empujado a una pila en algún lugar y restaurado de nuevo cuando se sale del alcance local. Al usar my en una variable, simplemente se crea una variable completamente nueva que sombrea la variable anterior con el mismo nombre; la anterior está completamente intacta y no necesita guardarse en ninguna parte. Simplemente está al acecho cuando se sale del alcance local y es visible de nuevo.

Empujar/hacer estallar a una pila requiere recursos; hay mucho trabajo bajo el capó para garantizar que esto funcione correctamente. (Considere casos como una excepción lanzada en el ámbito local o un controlador de señal que se está ejecutando. Estoy seguro de que puede pensar en más.)

Además de ser más eficiente, usar my es mucho más lógico. Como programador que introduce una variable local $ foo, no tiene que preocuparse por la razón semántica de la versión anterior de $ foo, qué datos pueden estar ya en ella, o de hecho si fue a $ foo ya creado. Si en algún momento de la ruta se elimina la declaración anterior de $ foo, su código local $foo se romperá, pero my $foo estará perfectamente satisfecho. Sea un buen programador y mantenga su código en piezas bien encapsuladas, lo que significa usar el alcance léxico tanto como pueda. Es bastante posible escribir una aplicación grande y nunca necesitar variables del paquete/alcance global en absoluto, especialmente cuando se usan clases OO bien diseñadas.

+3

@Evan Carroll: no, usa una pila llamada savestack – ysth

+8

Específicamente, hay un "bloc de notas léxicas" que ya se ha asignado para cada ámbito léxico en el que Perl coloca el nuevo léxico. Cuando sale el alcance, el bloc de notas desaparece. Además, local() tiene que ocuparse de la localización y restauración de elementos de matriz y hash individuales ('local $ h {key}'). Finalmente, las variables vinculadas son tratadas de manera especial por local, sus métodos FETCH y STORE son llamados cuando son localizados y restaurados. Cualquier cosa que tenga que considerar la vinculación es más lenta porque tiene que verificar si una variable está atada. – Schwern

12

local es probablemente más lento debido a la necesidad de guardar el valor anterior, pero la velocidad de local vs my no debe entrar en la discusión en absoluto. El ahorro de velocidad es minúsculo:

  Rate local my 
local 7557305/s -- -2% 
my 7699334/s 2% -- 

y las características de ambos son radicalmente diferentes. Los resultados anteriores provienen del siguiente punto de referencia:

#!/usr/bin/perl 

use strict; 
use warnings; 

use Benchmark; 

our $x; 

my %subs = (
    local => sub { 
     local $x = 42; 
     return $x; 
    }, 
    my => sub { 
     my $x = 42; 
     return $x; 
    } 
); 

for my $sub (keys %subs) { 
    print "$sub: ", $subs{$sub}(), "\n"; 
} 

Benchmark::cmpthese -1, \%subs; 
+3

La diferencia de velocidad sería mucho más evidente cuando presente algunos de los casos que Schwern describió en mi respuesta. – Ether

Cuestiones relacionadas