Habla sobre la eficiencia de las matrices de Python

Si necesitamos una lista que contenga solo números, entonces el método de matriz es más eficiente que el método de lista. Y las matrices también admiten todas las operaciones relacionadas con secuencias de variables, como eliminar un elemento de una lista (.pop), insertar un elemento (.insert) y agregar varios valores de otra secuencia al final de la lista (.extend ). Además, las matrices también definen métodos más eficientes para leer archivos (.frombytes) y escribir (.tofile).

La creación de una matriz requiere un código de tipo, como matriz ('d'). Este código de tipo se utiliza para representar el tipo de datos del lenguaje C implementado en la parte inferior. Generalmente, la capa inferior de Python que usamos está escrita e implementada en lenguaje C, por lo que también se llama CPython.

Python define los siguientes códigos de tipo:

Código de tipo Tipo C Tipo de Python Bytes ocupados Comentario
'segundo' char firmado En t 1
'SEGUNDO' char sin firmar En t 1
'u' Py_UNICODE Caracteres Unicode 2 (1)
'h' firmado corto En t 2
'H' corto sin firmar En t 2
'yo' firmado int En t 2
'YO' int sin firmar En t 2
'l' firmado largo En t 4
'L' largo sin firmar En t 4
'q' firmado mucho tiempo En t 8
'Q' sin firmar mucho tiempo En t 8
'F' flotador flotador 4
're' doble flotador 8

Nota (1): El 'u' código de tipo corresponde al carácter unicode obsoleto ( Py_UNICODE es decir  wchar_t) en Python . Dependiendo de la plataforma del sistema, puede ser de 16 o 32 bits.

Por ejemplo, el código de tipo b representa un carácter con signo. La matriz creada por matriz ('b') solo puede almacenar un entero del tamaño de un byte, entre -128 y 127. Con esta restricción, incluso si la secuencia es muy larga y tiene muchos números, puede ahorrar espacio.

Si la matriz tiene un tipo definido, no puede almacenar datos de tipos indefinidos.

Luciano Ramalho dio un ejemplo para ilustrar la eficiencia de las matrices. Primero cree una matriz de 10 millones de números aleatorios de punto flotante, luego escriba los datos y finalmente lea los datos.

from array import array
from random import random

floats = array('d', (random() for i in range(10 ** 7)))
logging.info('floats[-1] -> %s', floats[-1])

fp = open('floats.bin', 'wb')
floats.tofile(fp)
fp.close()

floats2 = array('d')
fp = open('floats.bin', 'rb')
floats2.fromfile(fp, 10 ** 7)
fp.close()
logging.info('floats2[-1] -> %s', floats2[-1])
logging.info('floats2==floats -> %s', floats2 == floats)

resultado de la operación:

INFO - floats[-1] -> 0.9160358679542017
INFO - floats2[-1] -> 0.9160358679542017
INFO - floats2==floats -> True

Analice el rendimiento del código a través del módulo cProfile y obtenga los siguientes resultados:

INFO -          192 function calls (180 primitive calls) in 0.098 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.061    0.061    0.061    0.061 {method 'fromfile' of 'array.array' objects}
        1    0.030    0.030    0.030    0.030 {method 'tofile' of 'array.array' objects}
        2    0.007    0.003    0.007    0.003 {built-in method io.open}
...

Se puede ver que solo se necesitan alrededor de 0.01 s para crear una matriz de 10 millones de números de punto flotante aleatorios e implementar operaciones de lectura y escritura de archivos. El tamaño del archivo generado es de aproximadamente 73M.

  1. Primero use la expresión del generador para crear un objeto iterable para **representar la potencia, y luego genere una matriz de punto flotante de doble precisión (el código de tipo es'd ');
  2. El valor de índice -1 de la matriz se puede obtener hasta el último elemento de la matriz;
  3. "Wb" es abrir el archivo en modo de escritura binaria, w es la abreviatura de escritura y b es la abreviatura de binario;

binario / ˈbaɪnəri
usando solo 0 y 1 como sistema de números

  1. Al crear una matriz, puede inicializar o crear una matriz vacía sin inicializar, como: matriz ('d');
  2. El segundo parámetro de entrada del método fromfile () se usa para especificar el rango máximo de valores;
  3. Puede ver que la matriz leída del archivo es exactamente la misma que la matriz almacenada.

Debido a que array.tofile escribe datos en un archivo binario, es mucho más rápido que escribir directamente en un archivo de texto. Según las estadísticas, la diferencia de rendimiento entre los dos será de casi 7 veces.

Supongo que te gusta

Origin blog.csdn.net/deniro_li/article/details/108900764
Recomendado
Clasificación