SWIG で配列の受け渡し。
MScriptUtil とかみてるといろいろ思うとこあるよね、というお話。
SWIG で適当に何パターンか書いてみて比較してみる。
ひととおりやってみた感じ、std::vector の右辺値参照を返り値にするのが一番よさそうだった。
まぁ当然といえば当然の話ではある。
適当な自前クラスのインスタンス配列なんかは、結局のところカスタムアロケータでTのデストラクトができるstd::vector
あともしかしてメモリ確保が超遅い?
テスト要件
- 任意個の整数配列に適当な値を詰める
比較パターン
テストコード
test.i
%module test %{ #include "test.h" %} %include "test.h" %include "carrays.i" %array_class(int, IntArray); %template (IntVector) std::vector<int>;
test.h
#pragma once #include <vector> inline void array(int* args, int len) { for (int i = 0; i < len; ++i) args[i] = i; } inline void vector(std::vector<int>* args, int len) { args->reserve(len); for (int i = 0; i < len; ++i) (*args)[i] = i; } inline std::vector<int> vector_value(int len) { std::vector<int> args; args.reserve(len); for (int i = 0; i < len; ++i) args[i] = i; return args; } inline std::vector<int> vector_rvalue(int len) { std::vector<int> args; args.reserve(len); for (int i = 0; i < len; ++i) args[i] = i; return std::move(args); }
test.py
import test import time length = 10000 loop = 100000 begin = time.time() args = test.IntArray(length) for i in xrange(loop): test.array(args, length) end = time.time() print "array pre-allocate", end - begin begin = time.time() for i in xrange(loop): args = test.IntArray(length) test.array(args, length) end = time.time() print "array allocate ", end - begin begin = time.time() args = test.IntVector() for i in xrange(loop): test.vector(args, length) end = time.time() print "vec* pre-allocate ", end - begin begin = time.time() for i in xrange(loop): args = test.IntVector() test.vector(args, length) end = time.time() print "vec* allocate ", end - begin begin = time.time() for i in xrange(loop): args = test.vector_value(length) end = time.time() print "vec value ", end - begin begin = time.time() for i in xrange(loop): args = test.vector_rvalue(length) end = time.time() print "vec rvalue ", end - begin
結果
- length = 10000
1> array pre-allocate 0.154000043869 1> array allocate 0.707999944687 1> vec* pre-allocate 0.569999933243 1> vec* allocate 1.1360001564 1> vec value 0.648000001907 1> vec rvalue 0.210999965668
- length = 100
1> array pre-allocate 0.0199999809265 1> array allocate 0.52999997139 1> vec* pre-allocate 0.0230000019073 1> vec* allocate 0.535000085831 1> vec value 0.0799999237061 1> vec rvalue 0.058000087738