07.12.2012 Views

versión color - PET: Python Entre Todos - Python Argentina

versión color - PET: Python Entre Todos - Python Argentina

versión color - PET: Python Entre Todos - Python Argentina

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

23 Vectorización<br />

El módulo struct y mmap nos puede ayudar mucho con esto. Imaginemos, pues, que tenemos un registro que son dos enteros<br />

de 32 bits más una cadena de 12 caracteres. En total, ocupará 20 bytes. Imaginemos, además, que queremos todo un array de<br />

estas cosas, 100 digamos. Ocupará, a lo mejor, 2000 bytes.<br />

>>> formato = 'ii 12s'<br />

>>> longitud = len(struct.pack(formato, 0, 0, ''))<br />

>>> buffer = mmap.mmap(-1, longitud*100)<br />

>>> buffer[0:longitud] = struct.pack(formato, 1, 2, 'hola')<br />

>>> struct.unpack(formato, buffer[0:longitud])<br />

(1, 2, 'hola\x00\x00\x00\x00\x00\x00\x00\x00')<br />

Ahí se podemos ver un pequeño inconveniente: la forma en que se guarda la cadena (con bytes nulos al final), pero cuando<br />

trabajemos con datos masivos y altamente estructurados (como registros de bases de datos), puede que sea una opción a tener<br />

en cuenta. En particular, si no querremos acceder muy frecuentemente a los datos.<br />

No es muy pythónico, pero la diferencia en uso de memoria es importante. El módulo mmap utiliza al sistema operativo para<br />

proveer un pedazo de memoria en el cual se puede escribir datos (de hecho, el pedazo de memoria puede mapearse a un archivo<br />

o compartir entre procesos). Pero es sólo eficiente si los datos van a ocupar más (mucho más) de 4kb, pues el sistema reserva<br />

una cantidad integral de páginas de memoria, no sólo bytes.<br />

La técnica puede funcionar igualmente bien con cadenas, con el inconveniente de que las cadenas no son mutables, así que<br />

cambiar su contenido conlleva el costo de copiar la estructura entera.<br />

Vectorización<br />

Esta técnica se puede llevar a una forma mucho más eficiente y cómoda de utilizar aplicando una técnica conocida como<br />

vectorización.<br />

Donde los registros de datos que usemos sean prominentemente numéricos, hay un módulo que nos permitirá guardar listas<br />

enteras de ellos de forma eficiente: array.<br />

>>> pos_x = array.array('i')<br />

>>> pos_y = array.array('i')<br />

>>> for i in xrange(1000):<br />

... pos_x.append(i)<br />

... pos_y.append(i)<br />

Eso creará dos arreglos de 1000 enteros, y ocupará exactamente lo que ocuparía ese mismo arreglo en C. Lo cual es muy<br />

eficiente. Y no es tan difícil de usar, puesto que array es idéntico a list en cuanto a su operación, con la diferencia de que<br />

sólo acepta un tipo predefinido de datos (i = integer, hay muchos otros), y los mantiene en memoria de forma realmente<br />

compacta y eficiente.<br />

De hecho, se puede armar una clase que funcione de “vista”:<br />

class Point(object):<br />

__slots__ = ('_x','_y','_i')<br />

def __init__(x, y, i):<br />

self._x = x<br />

self._y = y<br />

self._i = i<br />

@property<br />

def x(self):<br />

return self._x[self._i]<br />

@x.setter(self, value):<br />

self._x[self._i] = value<br />

@property<br />

def y(self):<br />

return self._y[self._i]<br />

<strong>Python</strong> <strong>Entre</strong> <strong>Todos</strong> (número 5, Marzo 2012) — http://revista.python.org.ar

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!