Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将大型字符串从Python传递到C++;扩展方法有效吗?_Python_C++_Python 3.x_Swig_Python Extensions - Fatal编程技术网

如何将大型字符串从Python传递到C++;扩展方法有效吗?

如何将大型字符串从Python传递到C++;扩展方法有效吗?,python,c++,python-3.x,swig,python-extensions,Python,C++,Python 3.x,Swig,Python Extensions,导言 我在做一个项目,需要处理大量的文本数据。许多相当大(数百MB)的文本文件。python就是需求(不要问为什么)。我想用C++扩展来提高性能。我决定和斯威格一起去。我有一个模式匹配算法,它比通常的python“string.find”(“模式”)要快得多。当我看到它用作python扩展时速度慢得多时,我很惊讶。这不应该发生。我想我很快就能找到原因,但需要你的帮助 问题 现在,我用类编写了一个简单的扩展,该类包含不做任何事情的方法(只需将字符串作为参数并返回数值(函数中没有处理): 什么都没有

导言

我在做一个项目,需要处理大量的文本数据。许多相当大(数百MB)的文本文件。python就是需求(不要问为什么)。我想用C++扩展来提高性能。我决定和斯威格一起去。我有一个模式匹配算法,它比通常的python“string.find”(“模式”)要快得多。当我看到它用作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
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
没什么。我

%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);
};
编译步骤:

#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
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
输出:

#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
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()更改为(我省略了标题):

那么结果正如预期的那样:

$ python3 test.py
Nothing time: 4.291534423828125e-06
Find time   : 0.10114812850952148

您可能希望将文件名传递给C并在那里打开和搜索。您正在读取字节,将这些字节转换为unicode,然后在计时部分内转换回字节。您可以阅读此处的文档以了解内部内容


如果文件是utf-8,则通过删除解码将其保留为字节,或者只传递文件名并用C加载它。

Python必须在调用之前创建一个非托管对象/
char*
/string(是的,这意味着分配和复制数据)。我想知道是否使用非Unicode“string”/byte数组(所有Python3字符串都是Unicode,这是对Python2.x的一个更改)将允许SWIG不复制的机会….?或者,也可以接受Python[string]没有隐式本机转换的对象本身?你在寻找类似的东西吗?我想你是在寻找更像这样的东西:谢谢,但我需要对字符串而不是文件进行操作。我将对这些字符串执行更多操作,因此每次从磁盘保存和加载不是解决我问题的好方法。我只需要将字符串引用到C++扩展名。