Введение
Я работаю над проектом, в котором необходимо обработать много текстовых данных.Многие довольно большие (сотни МБ) текстовые файлы.Питон является требованием (не спрашивайте почему).Я хочу использовать расширения C ++ для повышения производительности.Я решил пойти с SWIG.У меня есть алгоритм сопоставления с образцом, который намного быстрее, чем обычная строка Python ".Я был удивлен, когда увидел, что он намного медленнее, когда используется как расширение для Python.Этого не должно быть.Я думаю, что я достаточно близок, чтобы найти причину этого, но мне нужна ваша помощь.
Задача
Теперь я написал простое расширение с методом, содержащим класс, который НИЧЕГО не делает(просто взять строку в качестве параметра и вернуть числовое значение (в функции не выполняется обработка):
nothing.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;
}
nothing.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
Как видите, несмотря на то, что ничего не должно быть намного быстрее, чем найти () это намного медленнее!
Любая идея, если это можно как-то решить? Для меня это выглядит как данные преобразуются или копируются.
Почему я думаю, что все данные копируются? Потому чтоесли немного изменить функцию do_nothing () на (я опускаю заголовки):
int nothing::do_nothing() { // removed the argument
return this->zm;
}
Тогда результат будет таким, как ожидалось:
$ python3 test.py
Nothing time: 4.291534423828125e-06
Find time : 0.10114812850952148