我正在从一个大文件中读取列表,我最终希望将其存储为array.array
s. 因为
map(int, line.split())
非常慢,我写了一个小的 C 模块,它执行 strtok 和更快的 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 模块的 Python 版本int()
不会泄漏内存。
谢谢你的帮助!
编辑: 要验证我使用此脚本的模块:
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 更改了它。顺便说一句,将字符串复制到另一个内存位置不会改变行为。