[pyar] Compilador.py

Pablo Ziliani pablo en kultroom.com
Vie Jul 9 00:23:20 ART 2010


Pablo Ziliani wrote:
> Roberto Alsina wrote:
>> On Thursday 08 July 2010 23:16:38 Pablo Ziliani wrote:
>>  
>>> Pablo Ziliani wrote:
>>>    
>>>> pablo en pulp:~$ python -V
>>>> Python 2.6.4
>>>> pablo en pulp:~$ uname -a
>>>> Linux pulp 2.6.31-22-generic #60-Ubuntu SMP Thu May 27 00:22:23 UTC
>>>> 2010 i686 GNU/Linux
>>>> pablo en pulp:~$ python -m timeit "'archivo.py'.endswith('.py')"
>>>> 1000000 loops, best of 3: 0.541 usec per loop
>>>> pablo en pulp:~$ python -m timeit "'archivo.py'[-3:] == '.py'"
>>>> 1000000 loops, best of 3: 0.326 usec per loop
>>>>       
>>> ... lo cual no pretende ser un argumento para usarlo (de hecho y aunque
>>> es irrelevante, en el fondo creo que e quedo con endswith porque es más
>>> claro), simplemente me llamó la atención que un método que hace sólo 
>>> eso
>>> en particular sea menos eficiente que un slice.
>>>
>>> (perdón por el post doble pero me faltó poner eso en el email anterior)
>>>     
>>
>> Lo más probable es que la diferencia sea el lookup del método y la 
>> llamada nomás.
>
> puede ser, no sé cómo medir la llamada, pero:
>
> pablo en pulp:~$ python -m timeit -s 
> "archivo='archivo.py';endswith=archivo.endswith" "endswith('.py')"
> 1000000 loops, best of 3: 0.422 usec per loop
> pablo en pulp:~$ python -m timeit -s 
> "archivo='archivo.py';endswith=archivo.endswith" "archivo[-3:] == '.py'"
> 1000000 loops, best of 3: 0.322 usec per loop
>
> a ver...
>
> >>> archivo='archivo.py'
> >>> endswith = archivo.endswith
> >>> dis("endswith('.py')")
>          0 LOAD_NAME       25710 (25710)
>          3 <115>           26999
>          6 LOAD_GLOBAL     10344 (10344)
>          9 <39>
>         10 <46>
>         11 JUMP_IF_TRUE    10105 (to 10119)
>         14 STORE_SLICE+1
> >>> dis("archivo[-3:] == '.py'")
>          0 STORE_GLOBAL    25458 (25458)
>          3 BUILD_MAP       30313
>          6 JUMP_IF_FALSE   11611 (to 11620)
>          9 DELETE_SLICE+1
>         10 INPLACE_DIVIDE
>         11 FOR_ITER        15648 (to 15662)
>         14 DELETE_SUBSCR
>         15 SLICE+2
>         16 <39>
>         17 <46>
>         18 JUMP_IF_TRUE    10105 (to 10126)
>
> ¿y aura? me quedé sin ideas...

Esos dis están mal, no estoy muy ducho con eso.

Ya sé que es demasiado para lo intrascendente del asunto (que ya no es 
el del asunto...) y que no dice nada diferente de lo que ya dijiste 
acerca del costo de la llamada, pero no puedo evitar corregirme:

 >>> archivo = 'archivo.py'
 >>> endswith = archivo.endswith
 >>> ew = lambda:endswith('.py')
 >>> eq = lambda:archivo[-3:] == '.py'
 >>> dis(ew)
  1           0 LOAD_GLOBAL              0 (endswith)
              3 LOAD_CONST               0 ('.py')
              6 CALL_FUNCTION            1
              9 RETURN_VALUE
 >>> dis(eq)
  1           0 LOAD_GLOBAL              0 (archivo)
              3 LOAD_CONST               0 (-3)
              6 SLICE+1
              7 LOAD_CONST               1 ('.py')
             10 COMPARE_OP               2 (==)
             13 RETURN_VALUE
 >>> repeat(ew)
[0.72548699378967285, 0.71678709983825684, 0.71281194686889648]
 >>> repeat(eq)
[0.63371801376342773, 0.62568116188049316, 0.63154101371765137]

¿hay alguna forma de medir el costo del CALL_FUNCTION unicamente?



More information about the pyar mailing list