简介
我正在从事需要处理大量文本数据的项目。许多很大(数百MB)的文本文件。 python是必需的(不要问为什么)。我想使用C++扩展来提高性能。我决定选择SWIG。我有一个模式匹配算法,该算法比通常的python“string” .find(“pattern”)快得多。当我看到它用作python扩展时要慢得多时,我感到很惊讶。这不应该发生。我想我已经很接近找到原因了,但需要您的帮助。
问题
现在,我用类包含方法编写了一个简单的扩展,该方法不执行任何操作(只需将字符串作为参数并返回数字值(函数中未进行任何处理):
没什么。h:
#ifndef NOTHING_H
#define NOTHING_H
#include <string.h>
#include <iostream>
using namespace std;
class nothing {
protected:
int zm = 5;
public:
virtual int do_nothing(const char *empty);
};
#endif
没什么。cpp
#include "nothing.h"
int nothing::do_nothing(const char *empty) {
return this->zm;
}
没什么。i
%module nothing
%include <std_string.i>
using std::string;
using namespace std;
%{
#include "nothing.h"
%}
class nothing {
protected:
int zm = 5;
public:
virtual int do_nothing(const char *empty);
};
test.py
import nothing
import time
data = ""
with open('../hugefile', 'rb') as myfile:
data=myfile.read().decode(errors='replace')
n = len(data)
zm = nothing.nothing()
start = time.time()
res = zm.do_nothing(data)
end = time.time()
print("Nothing time: {}".format(end - start))
zm = nothing.nothing()
start = time.time()
res = data.find("asdasdasd")
end = time.time()
print("Find time : {}".format(end - start))
编译步骤:
swig -c++ -py3 -extranative -python nothing.i
g++ -fpic -lstdc++ -O3 -std=c++11 -c nothing.cpp nothing_wrap.cxx -I/usr/include/python3.7m
g++ -shared nothing.o nothing_wrap.o -o _nothing.so
输出:
$ python3 test.py
Nothing time: 0.3149874210357666
Find time : 0.09926176071166992
如您所见,尽管没有什么应该比find()快得多,但速度要慢得多!
知道是否可以通过某种方式解决?对我来说,数据似乎已转换或复制。
为什么我认为整个数据都被复制了?因为如果稍微将函数do_nothing()更改为(我省略标题),则:
int nothing::do_nothing() { // removed the argument
return this->zm;
}
然后结果如预期的那样:
$ python3 test.py
Nothing time: 4.291534423828125e-06
Find time : 0.10114812850952148
最佳答案
您可能需要将文件名传递给C,然后在其中打开并搜索。您正在读取字节,将这些字节转换为unicode,然后在定时部分内转换回字节。您可以在此处阅读文档以了解内部知识。
https://docs.python.org/3/c-api/unicode.html
如果文件是utf-8,则通过删除解码以字节为单位,或者仅传递文件名并将其加载到C中。