C++11の機能を活用した効率的な拡張Pythonモジュール開発

Shunichi Wakabayashi

Audience level:
Intermediate
Category:
Libraries and Extensions / ライブラリや拡張

Description

C++11で追加された右辺値参照、ユーザ定義リテラル、新しいfor構文、初期化リスト、ラムダ式等の新機能は、極めて小さいオーバーヘッドでスクリプト言語に近いシンプルな記述と高い柔軟性を提供しています。これらの機能を使用することで、複雑なPython APIを直接使用することなく、シンプルな記述でPythonとC++のコードを安全かつ少ないオーバーヘッドで連携させるラッパーライブラリを開発しています。 Pythonライクな記述でネイティブコードを生成するCythonとは異なり、Pythonから直接アクセスできるC++コードをシンプルに記述する、というアプローチで高速に動作するモジュール開発の可能性を模索しています。

Abstract

C++11で追加された右辺値参照、ユーザ定義リテラル、新しいfor構文、初期化リスト、ラムダ式等の新機能は、極めて小さいオーバーヘッドでスクリプト言語に近いシンプルな記述と高い柔軟性を提供しています。これらの機能を使用することで、複雑なPython APIを直接使用することなく、シンプルな記述でPythonとC++のコードを安全かつ少ないオーバーヘッドで連携させるラッパーライブラリを開発しています。 例えば、提案するライブラリとツールを用いることで、簡単な設定ファイルと、このようなコードを書くだけで、コンテナの中の実数の和と平均を同時に求めるPythonから呼び出し可能なメソッドを作成できます。 py::object sum_mean(const py::object &a) { double s=0; int n=0; for(auto &x: a){ s += *py::cast(x); ++n; } return py::tuple{ py::float(n), py::float(s/n) }; } これだけで、すべてのエラー(例えばaがiterableではなかった、コンテナの要素が実数ではなかった等)は補足され、適切に呼び出し元のPythonコードに例外として返されます。すべてのPythonオブジェクトの参照カウンタは適切に増減され、メモリリークを防ぎます。そして、Python APIを一個一個実行した場合と比べ、わずかなオーバーヘッドしかありません。 また、一つの共通のコードで、Python2.x, 3.xの双方の拡張モジュールを作成できます。 このラッパーライブラリでは、Pythonのモジュール、メソッド、ユーザ定義クラスとオブジェクトをC++の名前空間、関数、クラスとオブジェクトにマッピングすることで、自然なコーディングスタイルでの連携を目指しています。 Pythonライクな記述でネイティブコードを生成するCythonとは異なり、Pythonから直接アクセスできるC++コードをシンプルに記述する、というアプローチで高速に動作するモジュール開発の可能性を模索しています。 まだまだ開発途上で制約も多く、未公開の状態ですが、なにかの参考になればと思い、また有用なご指摘を頂ければと思いご紹介いたします。