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
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