[英]Shared library vs. opening a process performance
I have a certain base of Python code (a Flask server).我有一定的 Python 代码基础(Flask 服务器)。 I need the server to perform a performance-critical operation, which I've decided to implement in C++.
我需要服务器执行性能关键操作,我决定在 C++ 中实现该操作。 However, as the C++ part has other dependencies, trying out
ctypes
and boost.python
yielded no results (not found symbols, other libraries even when setting up the environment, etc., basically, there were problems ).但是,由于C++部分还有其他依赖,尝试了
ctypes
和boost.python
没有结果(没有找到符号,其他库甚至在设置环境时等等,基本上都有问题)。 I believe a suitable alternative would be for me to just compile the C++ part into an executable (a single function/procedure is required) and run it from python using commands
or subprocess
, communicating through stdin/out
for example.我相信一个合适的替代方案是我只需将 C++ 部分编译为可执行文件(需要单个函数/过程)并使用
commands
或subprocess
进程从 python 运行它,例如通过stdin/out
进行通信。 The only thing I'm worried about is that this will slow down the procedure enough to matter and since I'm unable to create a shared object library, calling its function from python directly, I cannot benchmark the speedup.我唯一担心的是这会减慢程序的速度,因为我无法创建共享的 object 库,从 python 调用它的 function 库,我无法直接进行基准测试。
When I compile the C++ code into an executable and run it with some sample data, the program takes ~5s
to run.当我将 C++ 代码编译成可执行文件并使用一些示例数据运行它时,程序需要
~5s
才能运行。 This does not account for opening the process from python, nor for passing data between the processes.这不考虑从 python 打开进程,也不考虑在进程之间传递数据。
The question is: How big of a speedup can one expect by using ctypes/boost with a SO compared to creating a new process to run the procedure?问题是:与创建一个新进程来运行该过程相比,通过使用带有 SO 的 ctypes/boost 可以期望多大的加速? If I regard the number to be big enough, it would motivate me to solve the encountered problems, basically, I'm asking if it's worth it .
如果我认为这个数字足够大,它会激励我解决遇到的问题,基本上,我是在问是否值得。
If you're struggling with creating binding using Boost.Python, you can manually expose your API via c-functions and use them via FFI.如果您在使用 Boost.Python 创建绑定时遇到困难,您可以通过 c 函数手动公开您的 API 并通过 FFI 使用它们。
Here's a simple example, which briefly explains my idea.这是一个简单的例子,它简要解释了我的想法。 At first, you create a shared library, but add some extra functions here, which in the example I put into
extern "C"
section.首先,您创建了一个共享库,但在此处添加了一些额外的函数,在示例中我将其放入
extern "C"
部分。 It's necessary to use extern "C"
since otherwise function names will be mangled and their actual names are likely to be different from those you've declared:必须使用
extern "C"
否则 function 名称将被破坏,并且它们的实际名称可能与您声明的名称不同:
#include <cstdint>
#include <cstdio>
#ifdef __GNUC__
#define EXPORT __attribute__ ((visibility("default")))
#else // __GNUC__
#error "Unsupported compiler"
#endif // __GNUC__
class data_processor {
public:
data_processor() = default;
void process_data(const std::uint8_t *data, std::size_t size) {
std::printf("processing %zu bytes of data at %p\n", size, data);
}
};
extern "C" {
EXPORT void *create_processor() {
return new data_processor();
}
EXPORT void free_processor(void *data) {
delete static_cast<data_processor *>(data);
}
EXPORT void process_data(void *object, const std::uint8_t *data, const std::uint32_t size) {
static_cast<data_processor *>(object)->process_data(data, size);
}
}
Then you create function bindings in python.然后在 python 中创建 function 绑定。 As you can see function declarations are almost the same as they are in the cpp file below.
如您所见,function 声明与下面的 cpp 文件中的声明几乎相同。 I used built-in types only (like
void *
, uint8_t
and anything, but I believe FFI allows you to declare and use custom structs as well):我只使用了内置类型(如
void *
、 uint8_t
和任何东西,但我相信 FFI 也允许您声明和使用自定义结构):
from cffi import FFI
mylib_api = FFI()
mylib_api.cdef("""
void *create_processor();
void free_processor(void *object);
void process_data(void *object, const uint8_t *data, uint32_t size);
""")
mylib = mylib_api.dlopen("mylib.so-file-location")
processor = mylib.create_processor()
try:
buffer = b"buffer"
mylib.process_data(processor, mylib_api.from_buffer("uint8_t[]", python_buffer=buffer), len(buffer))
finally:
mylib.free_processor(processor)
And that's basically it.基本上就是这样。
In my opinion inter-processing is going to be the last resort when nothing else works since:在我看来,当没有其他方法起作用时,交互处理将是最后的手段,因为:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.