Я хочу использовать protobuf, в частности реализацию cpp-generate-code для python.До сих пор у меня была сборка protobuf3.7 в cpp со статическим связыванием, я установил версию python с cpp_implementation, которая использует реализацию cpp -lection.
Отправной точкой для следующего шага было: Fast,Протоколные буферы native-C от Python , который предназначен для python2.Я закончил тем, что следовал этому руководству о том, как писать модули расширения cpython с использованием C ++ и пытаться подражать тому, что было сделано для тестов protobuf. * 1008 * https://github.com/protocolbuffers/protobuf/blob/master/benchmarks/python/py_benchmark.py и писать setup.py для него:
from distutils.core import setup, Extension
module1 = Extension('podpb',
include_dirs = ['C:\mydir\podpb\include'],
libraries = ['libprotobuf', 'my_other_lib_static'],
library_dirs = ['C:\mydir\podpb\lib',
'C:\mydir\otherlib\install\lib'],
sources = ['podpb.cpp'],
extra_compile_args = ['/MT'],
language='c++'
#extra_link_args = ['-static']
)
setup (name = 'ProtobufC',
version = '0.1',
packages = ['podpb'],
#cmdclass = {'build_ext': build_ext},
description = 'PB as a C module',
ext_modules = [module1])
podpb.cpp:
#include <Python.h>
#include "my_headers.pb.h"
...
static PyMethodDef PodMethods[] = {
{NULL, NULL, 0, NULL} /* Sentinel */
};
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"podpb", /* m_name */
"This is a module", /* m_doc */
-1, /* m_size */
PodMethods, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
PyMODINIT_FUNC
PyInit_podpb(void)
{
my_namespace::my_class().descriptor();
...
PyObject* m = PyModule_Create(&moduledef);
return m;
}
Теперь у меня есть podpb.cp36-win_amd64.pydи файл ProtobufC-0.1-py3.6.egg-info, и я пытаюсь использовать его как этот , просто импортируя его (import podpb в моем случае, например, импортировать libbenchmark_messages).В примере он вообще не используется, кроме импорта.
[update @ 2019/03/25] Я использую line_profiler для измерения производительности и не вижу каких-либо улучшений при переходе от cpp-отражения к сгенерированному cpp-коду.Вот эталонный скрипт:
import os
import podpb
def my_function(version):
some_path = 'something3' if (version == 3) else 'something'
this_path = os.path.dirname(os.path.realpath(__file__))
data_path = os.path.join(this_path, '..', 'data', some_path)
some_files = [x for x in os.listdir(data_path) if x.endswith('.bin')]
skey = lambda x : int(x.split('.')[0].split('_')[1])
some_packages = []
for fname in sorted(some_files, key=skey):
with open(os.path.join(data_path, fname), 'rb') as f:
some_packages.append(b"".join(f.readlines()))
return some_packages
@profile
def main():
from some3.place import SomeData as Data3
some_files = my_function(3)
o = Data3()
N = 1000
for i, some_msg in enumerate(some_files [:N]):
o.ParseFromString(some_msg)
print(i)
if __name__=='__main__':
main()
Правильно ли я это использую?
[/ update]