[Numpy-discussion] copying ctypes arrays to numarray?
Todd Miller
jmiller at stsci.edu
Thu Dec 16 13:56:01 CST 2004
I agree that numarray's .info() would be better as a string, but I've
been leery of changing it. Before we go to far with this, try:
repr(src._data)
to get a string like:
"<memory at 00815950 with size:256 held by object 00815930 aliasing object 00000000>"
Note: this technique depends on the buffer object used as the basis for
the array. Here the repr of numarray's memory object is giving useful
information. Other buffers, e.g. a string, might not.
It looks to me like you forgot to import Numeric so I don't think
there's any numarray:Numeric comparison going on... either that or I
just don't understand what you're to compare.
To be safe, check the .is_c_array() method.
Regards,
Todd
On Thu, 2004-12-16 at 13:33 -0800, rays wrote:
> I'm re-posting this here to see if anyone can shed light on
> numarray.info() behavior, and why assignment from a (ctypes.c_long *
> 2000)() to a numarray is so much slower than a memmove().
>
> I was surprised that assignment wasn't faster and that numarray
> assignment was consistently ~.5% faster than Numeric.
> The N vs. n memmove() flip-flopped for fastest, with array.array
> always slower.
>
> After some discussion, I made a better direct comparison of ctypes and
> memmove, map etc., using all the methods suggested so far. I think
> it's fairly valid.(?) Run on a 2.4GHz WinXP, Py2.3, a number of times.
>
> Parsing numarray.info() was a royal pain, it writes directly to
> stdout!
> I.e.:
> >>> inf = src.info()
> class: <class 'numarray.numarraycore.NumArray'>
> shape: (32,)
> strides: (8,)
> byteoffset: 0
> bytestride: 8
> itemsize: 8
> aligned: 1
> contiguous: 1
> data: <memory at 00815950 with size:256 held by object 00815930
> aliasing object
> 00000000>
> byteorder: little
> byteswap: 0
> type: Float64
> >>> inf
> >>> type(inf)
> <type 'NoneType'>
>
>
> Since the ctype does support slicing, I was considering leaving the
> data in the device driver buffer (~1MB circular) and poking into it,
> but memmove is so much faster than slicing the ctype, I'm doing
> memmove()s to numarray.
> I presume that I should check for numarray.iscontiguous( ) or
> is_c_array( ) first to be safe...
>
> Results and code below.
>
> Thanks to all for the help,
> Ray
>
>
>
> >python test.py
> Array address 11443208
> n address 17039424
> N address 21102656
> for loop 2027.0 us ea
> map 1781.0 us ea
> slice 1704.0 us ea
> assign N 1244.0 us ea
> assign n 1242.0 us ea
> memmove 4.3831 us ea
> memmove N 3.4773 us ea
> memmove n 3.4803 us ea
>
> _____________________________________________________
>
> ## test.py
> import array
> import numarray
> import ctypes
> import time
> import string
> import StringIO
> import sys
>
> buf = (ctypes.c_long * 2000)()
> Array = array.array("l", [0]*10000)
> n = numarray.zeros((1000000), numarray.Int32)
> N = numarray.zeros((1000000), numarray.Int32)
>
> #!!!!!!!!!!!!!!! arrrrgggg! !!!!!!!!!!!!!!!!
> # n.info() writes directly to stdout!
> stdout = sys.stdout
> fileo = StringIO.StringIO()
> sys.stdout = fileo
> n.info()
> ninfo = fileo.getvalue( )
> fileo.close()
> sys.stdout = stdout
>
> stdout = sys.stdout
> fileo = StringIO.StringIO()
> sys.stdout = fileo
> N.info()
> Ninfo = fileo.getvalue( )
> fileo.close()
> sys.stdout = stdout
> #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
>
> print 'Array address', Array.buffer_info()[0]
>
> ninfo = string.split(ninfo)
> nAddress = int(ninfo[20], 16)
> print 'n address', nAddress
> Ninfo = string.split(Ninfo)
> NAddress = int(Ninfo[20], 16)
> print 'N address', NAddress
>
> t0 = time.clock()
> for loop in range(1000):
> for i in range(2000):
> n[loop+i] = buf[i]
> print 'for loop ', round((time.clock()-t0)*1000), 'us ea'
>
> t0 = time.clock()
> for loop in range(1000):
> n[loop:loop+2000] = map(None, buf)
> print 'map ', round((time.clock()-t0)*1000), 'us ea'
>
> t0 = time.clock()
> for loop in range(1000):
> n[loop:loop+2000] = buf[0:2000]
> print 'slice ', round((time.clock()-t0)*1000), 'us ea'
>
> t0 = time.clock()
> for loop in range(10000):
> N[loop:loop+2000] = buf
> print 'assign N', round((time.clock()-t0)*100), 'us ea'
>
> t0 = time.clock()
> for loop in range(10000):
> n[loop:loop+2000] = buf
> print 'assign n', round((time.clock()-t0)*100), 'us ea'
>
> t0 = time.clock()
> for loop in range(10000):
> ctypes.memmove(10+Array.buffer_info()[0],
> buf,
> 2000)
> print 'memmove ', round((time.clock()-t0)*1, 4), 'us ea'
>
> t0 = time.clock()
> for loop in range(10000):
> ctypes.memmove(10+NAddress,
> buf,
> 2000)
> print 'memmove N', round((time.clock()-t0)*1, 4), 'us ea'
>
> t0 = time.clock()
> for loop in range(10000):
> ctypes.memmove(10+nAddress,
> buf,
> 2000)
> print 'memmove n', round((time.clock()-t0)*1, 4), 'us ea'
>
>
>
>
>
>
>
More information about the Numpy-discussion
mailing list