2017-03-13 3 views
1

sys.getsizeof(4)を呼び出すと、14が返されます。これがCのsizeof()と同じであると仮定すると、これは許容できないほど高くなります。整数の格納に使用するメモリの量を制限する方法は?

私は大きなバイト配列のようなメモリ配列を使いたいと思います。問題のプロジェクトの配列のサイズのために、メモリのオーバーヘッドが最も優先されます。移植性も大きな問題です。そのため、Cに落としたり、よりエキゾチックなライブラリを使用することは最適ではありません。

標準のPython 3のみを使用して、正の符号付きバイトリストまたはタプルメンバーに対して、より少ないメモリを使用する方法はありますか?

+1

ライブラリを使用できるのであれば、[numpy'](http://www.numpy.org/)は最適化された配列とそれらを操作するための効率的な機能を提供します。配列のdtypeパラメータを使用して要素のメモリサイズを指定できます。 – Craig

+1

適切な_タイプコードで 'array.array()'を使ってみてください。 – martineau

+0

marineauのコメントをフォロー:標準ライブラリの一部である['array'モジュール](https://docs.python.org/library/array.html)のドキュメント。 –

答えて

1

14私は、Pythonオブジェクトには少なくともa pointer to its type struct and a refcountがなければならないと考えています。

PyObject

すべてのオブジェクト型は、この型を拡張したものです。これは、Pythonがオブジェクトへのポインタをオブジェクトとして扱うために必要な情報を含む型です。通常の「リリース」ビルドでは、オブジェクトの参照カウントと対応する型オブジェクトへのポインタのみが含まれます。実際にPyObjectであると宣言されるものは何もありませんが、PythonオブジェクトへのポインタはすべてPyObject *にキャストできます。メンバーへのアクセスは、マクロPy_REFCNTとPy_TYPEを使用して行う必要があります。

このオーバーヘッドはすべてのPythonオブジェクトに与えられます。オーバーヘッド/ペイロードの比率を減らす唯一の方法は、例えば、配列(普通のPythonとnumpyの両方)のように、より多くのペイロードを持つことです。

ここでのトリックは、通常、配列要素はPythonオブジェクトではないため、refcountと型ポインタを不要にし、基礎となるC型と同じだけのメモリを占有することができます。

1

his commentためマーティへの帽子先端...)

あなただけの符号なしバイト(値が[0、255])に関係している場合は、最も簡単な答え内蔵かもしれませんbytearrayとその不変の兄弟で、bytes。 そのデフォルト__repr__は「紐状」、整数のではないリストであるので、一つの潜在的な問題は、これらはエンコードされた文字列(読み取りまたは外の世界への書き込み)を表すことを意図していることである。

>>> lst = [0x10, 0x20, 0x30, 0x41, 0x61, 0x7f, 0x80, 0xff] 
>>> bytearray(lst) 
bytearray(b'\x10 0Aa\x7f\x80\xff') 
>>> bytes(lst) 
b'\x10 0Aa\x7f\x80\xff' 

。なお、 '0''A'、および'a'は文字通り表示されますが、「印刷できない」値は'\x##'文字列エスケープシーケンスとして表示されます。 これらのバイトを整数のの束として考えると、これはあなたが望むものではありません。

固定幅の整数または浮動小数点数の均等配列(C言語とよく似ています)では、標準ライブラリのarray moduleを使用してください。より複雑なデータについては

>>> import array 

# One megabyte of unsigned 8-bit integers. 
>>> a = array.array('B', (n % 2**8 for n in range(2**20))) 
>>> len(a) 
1048576 
>>> a.typecode 
'B' 
>>> a.itemsize 
1 
>>> a.buffer_info() # Memory address, memory size. 
(24936384, 1048576) 

>>> a_slice = a[slice(1024, 1040)] # Can be sliced like a list. 
>>> a_slice 
array('B', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) 
>>> type(a_slice) # Slice is also an array, not a list. 
<class 'array.array'> 

struct moduleはずっとCのstructキーワードのように、異種のレコードを包装するためです。 Cとは異なり、arraystructにする明らかな方法はありません。

これらのデータ構造はすべて、PythonのBuffer Protocolを使用しています(CPythonでは少なくとも)Pythonクラスがその内部のCのような配列を他のPythonコードに直接公開することができます。 何か複雑なことをする必要がある場合は、これを学ぶ必要があるかもしれません... または、あきらめてNumPyを使用してください。

関連する問題