Comparación entera de Python (no igual a 0) puntos de referencia -- python campo con python-3.x campo con optimization campo con timing camp Relacionados El problema

Python integer comparison (not equal to 0) benchmarks


0
vote

problema

Español

Estaba haciendo un motor de física 2D en Python por diversión. Utilizo la velocidad de un objeto para determinar si debería ejecutar la detección de colisiones en ella. Es si su velocidad lo hará dentro de otro objeto en el siguiente ciclo, entonces ejecuto la detección de colisiones en él.

NOTA: Las velocidades X y Y son siempre enteros

Así que me di cuenta de que tendría que verificar que las velocidades X o Y del objeto sean menores o mayores que (no) 0.

Hay muchas maneras de hacer esto. Me fui con 4 métodos diferentes:

  def cmp1 (a,b):     return a > 0 or a < 0 or b > 0 or b < 0  def cmp2 (a, b):     return a != 0 or b != 0  def cmp3 (a, b):     return abs(a | b) > 0  def cmp4 (a, b):     return a | b != 0   

Me gusta el 4º método porque tiene menos operaciones y lee bien en inglés a or b does not equal 0

Pero de los 4 métodos, y del método de evaluación comparativa que utilicé, tiene el 2º tiempo promedio más lento que me sorprendió. De hecho, el primer método es el más rápido (nuevamente, utilizando el método de evaluación comparativa que utilicé).

Aquí está el método que solía resolver los horarios:

  def randints(min, max, amount):     return tuple([random.randint(min, max) for i in range(amount)])  times = [] for i in range(1000):     n = randints(-9999, 9999, 2)     t = time.time() * 1000     cmp4(*n)     t2 = time.time() * 1000     times.append(t2-t)  print('Average Time: ', sum(times)/len(times))   

Si ejecuto esta varias veces para cada método, obtengo resultados muy consistentes:

cmp1 - 0.00027s

cmp2 - 0.00032s

cmp3 - 0.00037s

cmp4 - 0.00035s

Entonces, mi pregunta es ¿Por qué el 4º método es tan lento en comparación con la primera? seguramente 2 operaciones (una bitwise, una comparación) debe ser más rápida que 4.

y, sí, sé que es una diferencia de solo un par de microsegundos.

Original en ingles

I was making a 2D physics engine in python for fun. I use an object's velocity to determine if I should run the collision detection on it. I.e if it's velocity would cause it to be inside another object on the next cycle, then I run the collision detection on it.

Note: x and y velocities are always integers

So I realised that I would have to check that the object's x or y velocities are either less than or greater than (not) 0.

There are a lot of ways to do this. I came up with 4 different methods:

def cmp1 (a,b):     return a > 0 or a < 0 or b > 0 or b < 0  def cmp2 (a, b):     return a != 0 or b != 0  def cmp3 (a, b):     return abs(a | b) > 0  def cmp4 (a, b):     return a | b != 0 

I like the 4th method because it has the fewest operations and reads well in English a or b does not equal 0

But of the 4 methods, and of the benchmarking method I used, it has the 2nd slowest average time which surprised me. In fact, the first method is the fastest (again, using the benchmarking method I used).

Here is the method I used to work out the timings:

def randints(min, max, amount):     return tuple([random.randint(min, max) for i in range(amount)])  times = [] for i in range(1000):     n = randints(-9999, 9999, 2)     t = time.time() * 1000     cmp4(*n)     t2 = time.time() * 1000     times.append(t2-t)  print('Average Time: ', sum(times)/len(times)) 

If I run this multiple times for each method, I get very consistent results:

cmp1 - 0.00027s

cmp2 - 0.00032s

cmp3 - 0.00037s

cmp4 - 0.00035s

So my question is why is the 4th method so slow compared to the first? surely 2 operations (one bitwise, one comparison) should be faster than 4.

And, yes, I know its a difference of only a couple of microseconds.

           
   
   

Lista de respuestas

2
 
vote
vote
La mejor respuesta
 

Hay mejores métodos de prueba

  y = [(random.randint(0,1), random.randint(0,1)) for _ in range(100_000)]  def test(cmp):     [cmp(a, b) for a, b in y]  %timeit test(cmp1) 20.1 ms ± 315 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) %timeit test(cmp2) 17.3 ms ± 212 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) %timeit test(cmp3) 29.3 ms ± 588 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) %timeit test(cmp4) 21.9 ms ± 289 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)   

La principal ventaja de or es que está cortocircuitando, efectivamente equivalente a:

  def or(a, b):     if a: return a     return b   

Considerando que | requiere una operación real (nivel muy bajo) a realizar, luego se debe crear un nuevo objeto entero de Python y luego se debe realizar otra operación.

Mi prueba usa una matriz que es un 50% ceros. Si hubiera un porcentaje más grande o menor de los ceros, los resultados pueden ser bastante diferentes.

En cualquier caso, olvidó el método más rápido de todos (ya que todos los números que no son cero son True ):

  def cmp0(a, b):     return a or b  bool(cmp0(0, 0)), bool(cmp0(-12, 0)), bool(cmp0(3.14, 0)) # --> (False, True, True)  %timeit test(cmp0) 12.8 ms ± 191 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)   

Sin embargo, si quisiera ser lo más claro posible (algo en el corazón de la programación en Python), usaría a != 0 or b != 0 .

 

There are better testing methods

y = [(random.randint(0,1), random.randint(0,1)) for _ in range(100_000)]  def test(cmp):     [cmp(a, b) for a, b in y]  %timeit test(cmp1) 20.1 ms xc2xb1 315 xc2xb5s per loop (mean xc2xb1 std. dev. of 7 runs, 10 loops each) %timeit test(cmp2) 17.3 ms xc2xb1 212 xc2xb5s per loop (mean xc2xb1 std. dev. of 7 runs, 100 loops each) %timeit test(cmp3) 29.3 ms xc2xb1 588 xc2xb5s per loop (mean xc2xb1 std. dev. of 7 runs, 10 loops each) %timeit test(cmp4) 21.9 ms xc2xb1 289 xc2xb5s per loop (mean xc2xb1 std. dev. of 7 runs, 10 loops each) 

The main advantage of or is that it is short circuiting, effectively equivalent to:

def or(a, b):     if a: return a     return b 

Whereas | requires an actual (very low level) operation to be performed, then a new python integer object to be created and then another operation to be performed.

My test uses an array which is 50% zeros. If there was a larger or smaller percentage of of zeros the results may be quite different.

In any case, you forgot the fastest method of all (since all non-zero numbers are True):

def cmp0(a, b):     return a or b  bool(cmp0(0, 0)), bool(cmp0(-12, 0)), bool(cmp0(3.14, 0)) # --> (False, True, True)  %timeit test(cmp0) 12.8 ms xc2xb1 191 xc2xb5s per loop (mean xc2xb1 std. dev. of 7 runs, 100 loops each) 

However if you wanted to be as clear as possible (something at the heart of programming in python), I'd use a != 0 or b != 0.

 
 
 
 

Relacionados problema

2  ¿Cómo puedo tener un temporizador rápido y de alta resolución en Windows?  ( How can i have a fast and high resolution timer on windows ) 
Estoy escribiendo un perfilador que consulta un temporizador cada vez que una función entra o sale. Por lo que es posible que sea consultado miles de veces u...

3  R: ¿Cómo hacer el sistema.time imprimir la expresión que se está cronometrada?  ( R how to make system time print the expression being timed ) 
Tengo una gran aglomeración de las funciones positive4 que se llama entre sí, pueden tardar mucho en el tiempo, los llamo usando positive5 : positive6...

1  Tiempo justo de dos funciones equivalentes con -O3  ( Fair timing of two equivalent functions with o3 ) 
Un compañero de trabajo enviado un código interesante, calcula el índice del LSB de un entero: unsigned int v; // the input number int r; // res...

0  setinterval, recursión, identificación del temporizador  ( Setinterval recursion timer id ) 
Tengo este ejemplo de animación de un tutorial que estoy viendo: (function() { var speed = 10, moveBox = function(moveBy) { var el = document.getEle...

2  La aplicación C # a C ++ DLL volver a la aplicación C # a través de devoluciones de llamada  ( C sharp app to c dll back to the c sharp app via callbacks ) 
Estoy escribiendo una aplicación C # que llama a un DLL de C ++. Este DLL es un controlador de dispositivo para un sistema de imágenes; Cuando se está adquiri...

3  Cómo obtener el tiempo del PGSQL DB  ( How to get timing from the pgsql db ) 
Estoy intentando obtener el tiempo de una consulta con la gema PG. Vi la documentación, pero no encontré nada. Quiero saber si hay algo así como class MyClas...

2  jQuery Fadeout Timing  ( Jquery fadeout timing ) 
Me gustaría que esta función desvanene los contenidos de la divutación, espere hasta que el fadeo sea terminado , luego desvanezca el nuevo calendario en. ¿Q...

0  Tiempo de marco en juegos  ( Frame timing in games ) 
He decidido convertirnos de hacer el tiempo basado en milisegundos para marcar el tiempo en mi juego de ritmo. Entiendo que puedo verificar el marco actual de...

3  ¿Cómo demore un programa VB.NET hasta que se complete una operación de archivo?  ( How do i delay a vb net program until a file operation completes ) 
Tengo esto: Dim myTemp As String myTemp = System.DateTime.Now().ToString("MMMddyyyy_HHmmss") & ".pdf" System.IO.File.Copy(myFile, "c:" & myTem...

8  % de tiempo equivalente en código  ( Timeit equivalent in code ) 
El comando mágico %timeit es ideal para medir los tiempos de ejecución de código de una manera interactiva. Sin embargo, quiero obtener el resultado de %ti...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos