大きなファイルからリストを読み取っていますが、最終的には s として保存したいと考えていarray.array
ます。なぜなら
map(int, line.split())
は非常に遅いので、strtok を実行する小さな C モジュールと、より高速なバージョンの atoi を作成しました。
inline long
minhashTables_myatoi(const char* s)
{
int r;
for (r = 0; *s; r = r * 10 + *s++ - '0');
return r;
}
static PyObject*
minhashTables_ints(PyObject *self, PyObject *args)
{
char* s;
Py_ssize_t slen;
if(!PyArg_ParseTuple(args, "s#", &s, &slen))
return NULL;
long* buf = malloc(sizeof(long) * (slen+1)/2);
const char* tok = strtok(s, " ");
buf[0] = minhashTables_myatoi(tok);
Py_ssize_t i;
for(i = 1; (tok = strtok(NULL, " ")) != NULL; i++)
buf[i] = minhashTables_myatoi(tok);
Py_ssize_t buflen = i;
PyObject* list = PyList_New(buflen);
PyObject *o;
for(i = 0; i < buflen; i++)
{
o = PyInt_FromLong(buf[i]);
PyList_SET_ITEM(list, i, o);
}
free(buf);
return list;
}
したがって、私の python スクリプトは文字列で呼び出し、それをコンストラクターにints()
渡し、結果の配列を.array.array
list
ints()
私の問題は、スクリプトがメモリをリークすることです。もちろん、関数ではなくマップでは発生しませんでした。
また、C モジュールを使用して独自のバージョンの Pythonint()
を使用しても、メモリ リークは発生しません。
ご協力いただきありがとうございます!
編集: モジュールをvalgrindするために、次のスクリプトを使用しました:
import minhashTables
data = ' '.join(map(str, range(10)))
print 'start'
foo = minhashTables.ints(data)
del data
del foo
print 'stop'
を実行しましたが、とvalgrind --tool=memcheck --leak-check=full --show-reachable=yes python test.py
の間に valgrind からの出力がないため、前後にトンがあります。start
stop
編集:リークしていることを確認するためのコード: import minhashTables
for i in xrange(1000000000):
data = ' '.join(map(str, range(10, 10000)))
foo = minhashTables.ints(data)
strtok によって変更されるため、文字列を再作成する必要があります。ちなみに、文字列を別のメモリ位置にコピーしても動作は変わりません。