RubyのMemoryView入門(1)
対象読者
Cは何となく文法とか分かるけどまともに書いたこと無いしメモリー管理などには不安が大きい RubyのC拡張ライブラリーの作り方は何となく知ってる
Init_xxxという関数を定義するとそれが呼ばれる、とかぐらい
つまり僕
MemoryViewとは
Rubyのあるオブジェクトが持っているデータ(インスタンス変数)を他のオブジェクトに渡すには、そのオブジェクトのメソッド引数にしたり、属性リーダーを作ったりすればよい。そこにコピーは発生せず、元のデータをそのまま共有できる。しかし、C拡張のCの部分で(計算やファイル読み込みによって)生まれたデータを、別のC拡張のオブジェクトに渡すには、Rubyを経由することになり、そこでコピーが発生してしまう。メモリーを食うし遅くなる。そうではなくて、C拡張の中であるメモリー領域を用意し、その場所を別のC拡張から触れるようにするのがMemoryView。
という理解。高速なCでデータを用意し、無駄なく他のC拡張でこれまた高速に処理しましょう。
題材
PCM 32ビットfloatの配列を作って他のC拡張に読ませるまでを題材と設定してみる。つまり、(PCMであることは置いといていいから)32ビットfloatの配列をMemoryViewを使って渡せるようにする。挫折したら変える。
何はともあれC拡張を作る
MemoryView以前にC拡張を作れねば仕方ない。
(TODO: 丁寧に説明)
code:ext/learning_memory_view/learning_memory_view.c
VALUE cFloatArray;
void
Init_learning_memory_view(void)
{
VALUE mod = rb_define_module("LearningMemoryView");
cFloatArray = rb_define_class_under(mod, "FloatArray", rb_cObject);
}
code:test/test_learning_memory_view.rb
require "test/unit"
require "learning_memory_view"
class TestLearningMemoryView < Test::Unit::TestCase
include LearningMemoryView
def test_initialize
assert_instance_of FloatArray, FloatArray.new
end
end
次
参考
Cのコードで説明されるので最初は辛いかも
何となくでいいからまず読もう
よく分からんこと
Ractor対応
どうしたらRactorセーフと見なせるの?