【问题标题】:how to use python to built an int arrray and manuplate it as efficient as C?如何使用python构建一个int数组并像C一样高效地操作它?
【发布时间】:2012-08-15 18:23:18
【问题描述】:

来自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 中做同样事情的好库?

【问题讨论】:

  • 您认为当前实现效率低的用例是什么?
  • @BurhanKhalid 我为这个问题添加了更多描述,a=[c_int(9)]*1024*1024 会比1M Bytes 使用更多吗?
  • 澄清一下:当您说“高效”时,您是什么意思?您想最小化挂墙时间、最小化 CPU 时间、最小化内存使用量还是其他方式?
  • @DanielPryden 主要针对内存使用情况,比如a=[c_int(9)]*1024*1024会不会比1M Bytes使用更多?
  • 无论如何您都不需要使用多个整数,因为在 Python 中 int 可以(实际上)是任意长度。

标签: python


【解决方案1】:

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

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

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

这里有几个相关链接:

【讨论】:

    【解决方案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 
    

    【讨论】:

      【解决方案3】:

      这个:

      a=[c_int()]
      

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

      将列表相乘只会复制引用,因此:

      a = [c_int()] * 1024 * 1024
      

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

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

      a = c_int * (1024 * 1024)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-31
        • 2012-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-15
        • 1970-01-01
        • 2021-08-30
        相关资源
        最近更新 更多