4

1つの機能を実行するC++プログラムがあります。大きなデータファイルを配列にロードし、整数の配列を受け取り、その配列でルックアップを実行して、単一の整数を返します。私は現在、次のように、引数として各整数を使用してプログラムを呼び出しています。

$ ./myprogram 1 2 3 4 5 6 7

私もrubyスクリプトを持っていますが、このスクリプトでc++プログラムを利用したいと思います。現在、私はこのようにやっています。

Rubyコード:

arguments = "1 2 3 4 5 6 7"
an_integer = %x{ ./myprogram #{arguemnts} }
puts "The program returned #{an_integer}" #=> The program returned 2283

これはすべて正常に機能していますが、私の問題は、rubyがこの呼び出しを行うたびに、c ++プログラムがデータファイル(100 MBを超える)をリロードする必要があることです。これは非常に遅く、非常に非効率的です。

C ++プログラムを書き直して、ファイルを1回だけロードし、毎回ファイルをリロードせずに、rubyスクリプトを介して多くのルックアップを実行できるようにするにはどうすればよいですか。ソケットを使用することは賢明なアプローチでしょうか?C ++プログラムをRuby拡張機能として作成しますか?

明らかに、私は経験豊富なc ++プログラマーではないので、あなたの助けに感謝します。

4

2 に答える 2

5

考えられるアプローチは、C ++プログラムを変更して、コマンドラインパラメーターではなく標準の入力ストリーム(std :: cin)から入力を受け取り、代わりに標準の出力(std :: cout)を介して結果を返すようにすることです。 mainの戻り値として。次に、Rubyスクリプトはpopenを使用してC++プログラムを起動します。

C++プログラムが現在次のようになっていると仮定します。

// *pseudo* code
int main(int argc, char* argv[])
{
    large_data_file = expensive_operation();

    std::vector<int> input = as_ints(argc, argv);
    int result = make_the_computation(large_data_file, input);

    return result;
}

次のようなものに変換されます。

// *pseudo* code
int main(int argc, char* argv[])
{
    large_data_file = expensive_operation();

    std::string input_line;
    // Read a line from standard input
    while(std:::getline(std::cin, input_line)){
        std::vector<int> input = tokenize_as_ints(input_line);
        int result = make_the_computation(large_data_file, input);

        //Write result on standard output
        std::cout << result << std::endl;
    }

    return 0;
}

そして、Rubyスクリプトは次のようになります

io = IO.popen("./myprogram", "rw")
while i_have_stuff_to_compute
    arguments = get_arguments()
    # Write arguments on the program's input stream
    IO.puts(arguments)
    # Read reply from the program's output stream
    result = IO.readline().to_i();
end

io.close()
于 2010-02-18T13:52:41.057 に答える
3

上手、

これについては、さまざまな方法で行うことができます。

1)これを行うための簡単で、潜在的に醜い方法は、c ++を実行してファイルを断続的にチェックし、rubyスクリプトに引数を含むファイルを生成させることです。次に、C ++プログラムは、含まれている引数を使用して、結果をrubyスクリプト内で待機できる結果ファイルに返します...これは明らかにHACK TASTICですが、実装は非常に簡単で、機能します。

2)c++コードをrubyのac拡張として公開します。これは、特にRICEを使用していて、ハッキーソリューションが大幅に少ない場合は、思ったほど難しくはありません。

3)c ++をacヘッダーファイルで公開できる場合は、FFIを使用してブリッジを構築するのはほとんど簡単です。Jeremy Hinegardnerが、rubyconfでFFIインターフェイスの構築について優れた講演を行いました。スクリーンキャストはこちらです

4)D-Busはアプリケーション通信バスを提供します。C++アプリを変更して、上記のイベントバスを利用し、ruby-dbusを使用してrubyからメッセージを渡すことができます。

もちろん、他にも千のルートがあります...たぶんこれらのいずれかが実行可能であることが証明されるかもしれません:)

乾杯!

于 2010-02-18T14:00:48.053 に答える