Как использовать реализацию protobuf для python3 с помощью cpp-generate-code? - PullRequest
1 голос
/ 20 марта 2019

Я хочу использовать 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]

...