Colección de citas famosas - Mensajes de felicitación - ¿Por qué la clasificación integrada de Python es 100 veces más rápida que su propia clasificación rápida?

¿Por qué la clasificación integrada de Python es 100 veces más rápida que su propia clasificación rápida?

La razón principal es que las funciones integradas están escritas en C y, de todos modos, no se puede crear una rueda de funciones integradas en Python. Es por eso que los usuarios de los lenguajes C y C++ a menudo prefieren los bucles a los algoritmos básicos. Porque los usuarios de C/C++ tienen las condiciones para escribir algoritmos que sean comparables a la biblioteca estándar, pero muchos lenguajes de alto nivel no pueden. No es que las habilidades del programador sean pobres, es que las condiciones objetivas simplemente no pueden hacerlo.

Por ejemplo, el lenguaje Java no tiene una rueda de cadenas artificial, y C++ tiene innumerables implementaciones de la clase de cadena sola. ¿Es porque los usuarios de C+ prefieren escribir clases de cadenas? Obviamente no, en parte porque el lenguaje Java no puede crear una rueda que pueda igualar el algoritmo de la biblioteca estándar incorporada de Java, pero C++ sí. Otra razón triste es que las funciones de cadena de la biblioteca estándar de C ++ son demasiado débiles. Las funciones de clase de cadena de la mayoría de los lenguajes de alto nivel son más potentes que las de la biblioteca estándar de C ++.

Una gran ilusión al escribir C++ es que creo que puedo ser más rápido que la biblioteca estándar, y el mismo principio se puede aplicar en Python. Ya sean los paquetes de uso común de Python o las funciones integradas, básicamente están optimizados para escenarios reales. Los algoritmos que escribo yo mismo generalmente no son tan eficientes como los algoritmos integrados, por lo que no se les recomienda que hagan ruedas cuando los usan. Pitón.

Volviendo a esta pregunta, la clasificación integrada de Python es esencialmente una función implementada en C. La eficiencia de ejecución será mucho más rápida que la de Python y se utilizarán diferentes algoritmos de clasificación según los diferentes tamaños de datos. por lo tanto, la eficiencia generalmente será mejor que la clasificación manual en Python, sin mencionar que escribir Quicksort9 basado en recursividad llevará mucho tiempo adicional.

Debido a que la clasificación incorporada de Python está escrita en C, definitivamente puedes hacerlo igual de rápido si lo escribes en C o C++. No sé la razón específica por la que la eficiencia informática de Python es 100 veces más lenta que la del lenguaje C, pero como muchos grandes de Zhihu han explicado este problema, no lo haré aquí.

También existe timsort. Quick sort es la familia de algoritmos con el mejor rendimiento promedio entre todos los algoritmos de clasificación de comparación, como unstable_sort y rust en C++. Quizás en algunos casos, como cuando la matriz está casi ordenada, la clasificación por sincronización será más rápida que la clasificación rápida. Pero si proporciona una matriz a voluntad, como ordenar aleatoriamente un número de 1 millón de tamaño como lo hizo el interrogador, y luego ordenarlo, timsort nunca será más rápido que la clasificación rápida. Absolutamente imposible. Esta velocidad de 100x no tiene nada que ver con timsort.

Soy programador de C/C++ y puedo decirles con responsabilidad que si C ocupa el segundo lugar, nadie se atreverá a ocupar el primer lugar. Entonces, supongo que Python y muchos otros lenguajes de alto nivel saltarán directamente a bibliotecas estáticas y dinámicas escritas en C de vez en cuando. Yo mismo hice muchas ruedas, algunas de las cuales recién estaba comenzando. No estaba familiarizado con la API del sistema y las bibliotecas de funciones, por lo que no pude encontrar una adecuada, así que hice las ruedas yo mismo. Luego encontré algo mejor y abandoné lo que había escrito. Pero no descarto que en parte se deba a que personalmente creo que hay margen de optimización, así que reconstruí una rueda en lenguaje C que es más eficiente que la existente.

Entonces, el creador de los lenguajes de alto nivel es realmente C. En términos de eficiencia de ejecución, y mucho menos Python, JAVA, C#, VB, incluso C++, el hijo de C, no se pueden comparar con C en las manos del mismo programador. Por lo tanto, estos lenguajes están en cola para ser suspendidos por C, razón por la cual los lenguajes de alto nivel como Python tienen sus propias funciones disponibles.

Todas las funciones de la biblioteca integrada están implementadas en C, que es definitivamente más eficiente que los programas Python escritos a mano. Además, la clasificación incorporada Timsort ha optimizado mucho el algoritmo de clasificación de Onlogn en comparación con la complejidad temporal de los cursos de pregrado. Por lo tanto, para la gente común, no esperan que la eficiencia de las cosas puramente escritas a mano sea comparable a la de los estudiantes. biblioteca estándar. Además, la clasificación de temas principales no puede pasar de la simple clasificación de temas en LeetCode. Seleccionar pivotes aleatoriamente es la optimización más básica de clasificación rápida. Aunque el tema principal son los números aleatorios, definitivamente no es la razón principal de la baja eficiencia.

Entonces, py casi tiene que desmantelar su propio cuerpo de bucle. Esta es la brecha de rendimiento entre py y c/c++.

Debemos intentar utilizar funciones integradas y numpy para procesar datos. Una vez que el cuerpo del bucle está escrito a mano, debes saber que puede ser cien veces más lento. Por ejemplo, cuando usé la versión py de opency, accidentalmente escribí un bucle doble para procesar datos, lo cual fue un sentimiento amargo. Sin embargo, cppc# es libre de escribir bucles con punteros cuando participa en opencv, por lo que en realidad no necesitan el componente numpy y tienen suficiente rendimiento y flexibilidad para manejar esto.

La clasificación integrada de Cpp es una combinación de clasificación rápida y clasificación en montón. La peor complejidad temporal es nlogn, mientras que la peor complejidad temporal de clasificación rápida es n2. En cuanto a la clasificación dentro de Python, creo que es una verdad, no una simple clasificación rápida. Como ejemplo simple, cuando sus datos ya están en orden, ciertamente no es apropiado pasarlos a ordenación rápida. Luego, cuando configure la función de clasificación, ¿no sería mejor codificarla con anticipación y luego ordenarla rápidamente? Por supuesto que no será tan sencillo, pero creo que la interfaz proporcionada por el gobierno es muy sutil y vale la pena aprenderla.

Por un lado, la función de clasificación en Python está escrita en lenguaje C, y la clasificación en C++ es una mezcla de clasificación rápida, inserción directa y clasificación en montón. Cuando la cantidad de datos es grande, se usa primero la clasificación rápida. Cuando la cantidad de datos es pequeña, se usa la inserción directa, porque cuando la cantidad de datos es pequeña, cada parte de la clasificación rápida está básicamente en orden, lo cual está cerca de. la complejidad temporal óptima de la inserción directa O (n), un poco mejor que la clasificación rápida.

Por otro lado, su implementación subyacente es la ordenación por fusión. Simplemente utiliza la implementación subyacente que no se puede escribir en Python, lo que evita muchos gastos generales adicionales en el propio Python. Esto es mucho más rápido que la clasificación por combinación que escribimos nosotros mismos, por lo que generalmente intentamos usar sorted y sort.