PHP in_array () rendimiento horrible. La mejor forma de buscar matriz por valor

Tengo el siguiente código simple para probar contra la colisión en una clave principal que estoy creando:

$machine_ids = array(); for($i = 0; $i < 100000; $i++) { //Generate machine id returns a 15 character alphanumeric string $mid = Functions::generate_machine_id(); if(in_array($mid, $machine_ids)) { die("Collision!"); } else { $machine_ids[] = $mid; } } die("Success!"); 

¿Alguna idea de por qué esto lleva muchos minutos correr? De todos modos para acelerarlo?

 for($i = 0; $i < 100000; $i++) { //Generate machine id returns a 15 character alphanumeric string $mid = Functions::generate_machine_id(); if (isset($machine_ids[$mid])) { die("Collision!"); } $machine_ids[$mid] = true; } 

Para esto, use $mid como claves y el valor ficticio como valor. Específicamente, en lugar de

 if(in_array($mid, $machine_ids)) { die("Collision!"); } else { $machine_ids[] = $mid; } 

utilizar

 if(isset($machine_ids[$mid])) { die("Collision!"); } else { $machine_ids[$mid] = 1; } 

Al final puedes extraer la matriz que originalmente querías con array_keys($machine_ids) .

Esto debería ser mucho más rápido. Si todavía es lento, sus Functions::generate_machine_id() es lento.

EDITADO para agregar isset según los comentarios.

La comprobación de la membresía de la matriz es una operación O (n), ya que debe comparar el valor con cada elemento de la matriz. Después de agregar un montón de cosas a la matriz, naturalmente se vuelve más lento.

Si necesita realizar un montón de pruebas de membresía, como es el caso aquí, debe usar una estructura de datos diferente que admita O (1) pruebas de membresía, como un hash.

Refactorice su código para que use una matriz asociada para contener las ID de la máquina y use isset para verificar

 if( isset($machine_id[$mid]) ) die("Collision"); $machine_ids[$mid] = $mid; 

El uso de isset debería ser más rápido