如何使用python构建一个int数组并像C一样高效地操作它?

时间:2012-08-15 18:23:19

标签: python

来自http://www.cs.bell-labs.com/cm/cs/pearls/sol01.html

C代码是这样的:

#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1 + N/BITSPERWORD];

void set(int i) {        a[i>>SHIFT] |=  (1<<(i & MASK)); }
void clr(int i) {        a[i>>SHIFT] &= ~(1<<(i & MASK)); }
int  test(int i){ return a[i>>SHIFT] &   (1<<(i & MASK)); }

我找到了ctypesBitArraysnumpy,但我不确定它们是否能像上面的C代码那样高效。

例如,如果我写这样的代码:

from ctypes import c_int
a=[c_int(9)]*1024*1024

使用的空间是1M字节还是更多?

有没有人知道一些可以用Python做同样事情的好库?

3 个答案:

答案 0 :(得分:3)

Numpy或ctypes都是不错的选择。但是你确定你的Python代码真的需要像C一样有效吗?你确定这段代码是性能热点吗?

最好的办法是使用Python分析器来确保此代码确实需要像C一样高效。如果确实如此,那么将代码保存在C中并链接到最简单可能是最简单的它使用类似ctypes或SWIG的东西。

编辑:为了回答您更新的问题,一个大小为N且元素大小为M的numpy数组将包含N * M个字节的连续内存,以及一个标题和一些视图字节。

以下是几个相关链接:

答案 1 :(得分:2)

您还可以查看内置的array模块:

>>> import array
>>> help(array)
Help on built-in module array:

NAME
    array

FILE
    (built-in)

DESCRIPTION
    This module defines an object type which can efficiently represent
    an array of basic values: characters, integers, floating point
    numbers.  Arrays are sequence types and behave very much like lists,
    except that the type of objects stored in them is constrained.  The
    type is specified at object creation time by using a type code, which
    is a single character.  The following type codes are defined:

        Type code   C Type             Minimum size in bytes 
        'b'         signed integer     1 
        'B'         unsigned integer   1 
        'u'         Unicode character  2 (see note) 
        'h'         signed integer     2 
        'H'         unsigned integer   2 
        'i'         signed integer     2 
        'I'         unsigned integer   2 
        'l'         signed integer     4 
        'L'         unsigned integer   4 
        'f'         floating point     4 
        'd'         floating point     8 

答案 2 :(得分:1)

此:

a=[c_int()]

创建一个包含对c_int对象的引用的列表。

乘以列表只会复制引用,所以:

a = [c_int()] * 1024 * 1024

实际上创建了一个1024 * 1024个对相同单个c_int对象的引用列表。

如果你想要一个1024 * 1024 c_ints的数组,请执行以下操作:

a = c_int * (1024 * 1024)