mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 21:25:13 +00:00
FAQ improvements
This commit is contained in:
parent
8cb6cb33ef
commit
c79dbe425d
@ -5,7 +5,7 @@ Changelog
|
|||||||
|
|
||||||
1.5 (not yet released)
|
1.5 (not yet released)
|
||||||
----------------------
|
----------------------
|
||||||
* For polymorphic types, use RTTI to try to return the closest type registered with pybind11.
|
* For polymorphic types, use RTTI to try to return the closest type registered with pybind11
|
||||||
* Pickling support for serializing and unserializing C++ instances to a byte stream in Python
|
* Pickling support for serializing and unserializing C++ instances to a byte stream in Python
|
||||||
* Added a convenience routine ``make_iterator()`` which turns a range indicated
|
* Added a convenience routine ``make_iterator()`` which turns a range indicated
|
||||||
by a pair of C++ iterators into a iterable Python object
|
by a pair of C++ iterators into a iterable Python object
|
||||||
|
98
docs/faq.rst
98
docs/faq.rst
@ -97,3 +97,101 @@ that that were ``malloc()``-ed in another shared library, using data
|
|||||||
structures with incompatible ABIs, and so on. pybind11 is very careful not
|
structures with incompatible ABIs, and so on. pybind11 is very careful not
|
||||||
to make these types of mistakes.
|
to make these types of mistakes.
|
||||||
|
|
||||||
|
How can I reduce the build time?
|
||||||
|
================================
|
||||||
|
|
||||||
|
It's good practice to split binding code over multiple files, as is done in
|
||||||
|
the included file :file:`example/example.cpp`.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
void init_ex1(py::module &);
|
||||||
|
void init_ex2(py::module &);
|
||||||
|
/* ... */
|
||||||
|
|
||||||
|
PYBIND11_PLUGIN(example) {
|
||||||
|
py::module m("example", "pybind example plugin");
|
||||||
|
|
||||||
|
init_ex1(m);
|
||||||
|
init_ex2(m);
|
||||||
|
|
||||||
|
/* ... */
|
||||||
|
|
||||||
|
return m.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
The various ``init_ex`` functions are contained in separate files that can be
|
||||||
|
compiled independently from another. Following this approach will
|
||||||
|
|
||||||
|
1. enable parallel builds (if desired).
|
||||||
|
|
||||||
|
2. allow for faster incremental builds (e.g. if a single class definiton is
|
||||||
|
changed, only a subset of the binding code may need to be recompiled).
|
||||||
|
|
||||||
|
3. reduce memory requirements.
|
||||||
|
|
||||||
|
How can I create smaller binaries?
|
||||||
|
==================================
|
||||||
|
|
||||||
|
To do its job, pybind11 extensively relies on a programming technique known as
|
||||||
|
*template metaprogramming*, which is a way of performing computation at compile
|
||||||
|
time using type information. Template metaprogamming usually instantiates code
|
||||||
|
involving significant numbers of deeply nested types that are either completely
|
||||||
|
removed or reduced to just a few instrutions during the compiler's optimization
|
||||||
|
phase. However, due to the nested nature of these types, the resulting symbol
|
||||||
|
names in the compiled extension library can be extremely long. For instance,
|
||||||
|
the included test suite contains the following symbol:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
__ZN8pybind1112cpp_functionC1Iv8Example2JRNSt3__16vectorINS3_12basic_stringIwNS3_11char_traitsIwEENS3_9allocatorIwEEEENS8_ISA_EEEEEJNS_4nameENS_7siblingENS_9is_methodEA28_cEEEMT0_FT_DpT1_EDpRKT2_
|
||||||
|
|
||||||
|
which is the mangled form of the following function type:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
pybind11::cpp_function::cpp_function<void, Example2, std::__1::vector<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, std::__1::allocator<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > > >&, pybind11::name, pybind11::sibling, pybind11::is_method, char [28]>(void (Example2::*)(std::__1::vector<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, std::__1::allocator<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > > >&), pybind11::name const&, pybind11::sibling const&, pybind11::is_method const&, char const (&) [28])
|
||||||
|
|
||||||
|
The memory needed to store just the name of this function (196 bytes) is larger
|
||||||
|
than the actual piece of code (111 bytes) it represents! On the other hand,
|
||||||
|
it's silly to even give this function a name -- after all, it's just a tiny
|
||||||
|
cog in a bigger piece of machinery that is not exposed to the outside world.
|
||||||
|
So we'll generally only want to export symbols for those functions which are
|
||||||
|
actually called from the outside.
|
||||||
|
|
||||||
|
This can be achieved by specifying the parameter ``-fvisibility=hidden`` to GCC
|
||||||
|
and Clang, which sets the default symbol visibility to *hidden*. It's best to
|
||||||
|
do this only for release builds, since the symbol names can be helpful in
|
||||||
|
debugging sessions. On Visual Studio, symbols are already hidden by default, so
|
||||||
|
nothing needs to be done there. Needless to say, this has a tremendous impact
|
||||||
|
on the final binary size of the resulting extension library.
|
||||||
|
|
||||||
|
Another aspect that can require a fair bit of code are function signature
|
||||||
|
descriptions. pybind11 automatically generates human-readable function
|
||||||
|
signatures for docstrings, e.g.:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
| __init__(...)
|
||||||
|
| __init__(*args, **kwargs)
|
||||||
|
| Overloaded function.
|
||||||
|
|
|
||||||
|
| 1. __init__(example.Example1) -> NoneType
|
||||||
|
|
|
||||||
|
| Docstring for overload #1 goes here
|
||||||
|
|
|
||||||
|
| 2. __init__(example.Example1, int) -> NoneType
|
||||||
|
|
|
||||||
|
| Docstring for overload #2 goes here
|
||||||
|
|
|
||||||
|
| 3. __init__(example.Example1, example.Example1) -> NoneType
|
||||||
|
|
|
||||||
|
| Docstring for overload #3 goes here
|
||||||
|
|
||||||
|
|
||||||
|
In C++11 mode, these are generated at run time using string concatenation,
|
||||||
|
which can amount to 10-20% of the size of the resulting binary. If you can,
|
||||||
|
enable C++14 language features (using ``-std=c++14`` for GCC/Clang), in which
|
||||||
|
case signatures are efficiently pre-generated at compile time. Unfortunately,
|
||||||
|
Visual Studio's C++14 support (``constexpr``) is not good enough as of April
|
||||||
|
2016, so it always uses the more expensive run-time approach.
|
||||||
|
Loading…
Reference in New Issue
Block a user