demasiado para Python???

Francesc Alted falted en openlc.org
Mar Mayo 6 13:49:14 CEST 2003


Mensaje citado por: Jaime Perea <jaime en iaa.es>:
> De todas maneras este es el típico algoritmo que caerá al final en las
> garras
> de algún compilador :-) 

Pues si, ya cayó ;-), pues aunque deberia estar haciendo otras cosas, esto de 
la optimización me "pica" demasiado.

Adjunto envio el código en Pyrex 
(http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/) para el cálculo que nos 
ocupa (calcul.pyx). He hecho una versión de la función de cálculo para 
precisión simple (calcula_simple) y otra para precisión doble (calcula_doble). 
La extensión se puede compilar con el sencillo setup.py que adjunto. Cuando 
esté compilado, se puede correr con el calcul2.py para ver las diferencias de 
velocidad (más de un factor 200!). También adjunto la extension compilada 
(calcul.pyd), por si no tenés compilador.

Bueno, y ahora me voy a currar en serio,

Francesc Alted
------------ próxima parte ------------
# Alguna rutinas de ayuda para la API de Python
cdef extern from "Python.h":
  # Para acceder a los buffers de los objetos numarray
  int PyObject_AsReadBuffer(object, void **rbuf, int *len)
  int PyObject_AsWriteBuffer(object, void **rbuf, int *len)

# Cálculos en precision simple
def calcula_simple(object arr, int jj, int n, float r):
    cdef void *buf
    cdef float *h
    cdef int i, j
    cdef int buflen, ret

    ret = PyObject_AsWriteBuffer(arr._data, &buf, &buflen)
    h = <float *>buf

    for i from 1 <= i < n+1:
        for j from 1 <= j < jj+1:
            h[j] = r  * h[j+1] + (1-2*r) * h[j] + r * h[j-1]
        h[jj+1] = h[jj-1]

# Cálculos en precisión doble
def calcula_double(object arr, int jj, int n, double r):
    cdef void *buf
    cdef double *h
    cdef int i, j
    cdef int buflen, ret

    ret = PyObject_AsWriteBuffer(arr._data, &buf, &buflen)
    h = <double *>buf

    for i from 1 <= i < n+1:
        for j from 1 <= j < jj+1:
            h[j] = r  * h[j+1] + (1-2*r) * h[j] + r * h[j-1]
        h[jj+1] = h[jj-1]

------------ próxima parte ------------
# Setup básico para compilar la extension
# Hace falta instalar Pyrex (http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/)
# Invocarlo como "python setup.py build_ext --inplace"

from distutils.core     import setup, Extension
from distutils.dep_util import newer
from Pyrex.Distutils import build_ext

setup(name = "prueba",
      ext_modules = [ Extension("calcul",["calcul.pyx"])],
      cmdclass = {'build_ext': build_ext}
)

------------ próxima parte ------------
# Metodo de diferencias finitas
# este programa resuelve onda de difusión
# con operardor de Lax.

from numarray import *
import time
import calcul  # Extension Pyrex. Acelera los cálculos más de un factor 200 (!)

jj = 50    # ultimo punto         x = 500 m
n = 10000    # pasos de tiempo     dt = 2hs (7200s)

ho = 5.    # condición de borde
h_to = 1.  # valor inicial

r = 0.108  # n curant <= 0.5

hs = zeros([jj+2],Float32)+ho  # Precision simple
hd = zeros([jj+2],Float64)+ho  # Precision doble
hs[0] = h_to
hd[0] = h_to

t1 = time.time()
calcul.calcula_simple(hs, jj, n, r)
t2 = time.time()

print hs
print "tiempo total simple precision:", t2 - t1

t1 = time.time()
calcul.calcula_double(hd, jj, n, r)
t2 = time.time()

print hd
print "tiempo total doble precision:", t2 - t1
------------ próxima parte ------------
A non-text attachment was scrubbed...
Name: calcul.pyd
Type: application/octet-stream
Size: 20480 bytes
Desc: no disponible
URL: <http://mail.python.org/pipermail/python-es/attachments/20030506/e7d1f962/attachment.obj>
------------ próxima parte ------------
_______________________________________________
Python-es mailing list
Python-es en aditel.org
http://listas.aditel.org/listinfo/python-es


Más información sobre la lista de distribución Python-es