ぺんぎんさんのおうち

日記です。たまに日記じゃないこともあります。

14.02.2024

はてなブログのUI変わったね。エントリを見る側からすると今のUIがカッコよくていいけど、書く側的には前のほうが好き(In my opnion)。

mpf_関数はmpf_t同士かmpf_tと整数の加減乗除しかない(mpq_t, mpz_tは考慮しない)。double型の場合はどうするか。mpf_tをinitし、mpf_set_dで値をセットしてからmpf_mulを呼び出す。
これの何が嫌かというと、mpf_classインスタンスとdoubleの乗算があるときに(たとえばこんなのmpf_class a(11.4514), b; b = a * 8.10;)、mpf_init2による動的メモリ確保が発生する。
std::vector<mpf_class>インスタンスの各要素にdouble型を足したり掛けたりするときに困ることになるので、この部分は自分で頑張って実装する。

// 一番良くない例
std::vector<mpf_class> mpf_vec(N); // define then initilize values.
double ct = 0.81019;
for (size_t i = 0; i < N; i++) {
    mpf_vec[i] = mpf_classインスタンス * ct // ctのためのメモリ確保がN回発生する。なんならfreeも走る。
}
// 改良版(まだ改善できるよ)
std::vector<mpf_class> mpf_vec(N); // define then initilize values.
mpf_class ct(0.81019); // mpf_tでもいい。ちゃんとmpf_initしてからmpf_set_dする。メモリ確保はここの一回だけ。
for (size_t i = 0; i < N; i++) {
    mpf_mul(mpf_vec[i].get_mpf_t(), mpf_classインスタンス.get_mpf_t(), ct.get_mpf_t());
}

しかしやることは単純で、mpf_t->_mp_dに動的メモリ確保した領域のアドレスではなくスタック領域のアドレスを渡すだけ。だいだい0.1 nsくらい速くなる。動的メモリ確保といってもサイズは小さいからmallocではなくbrkが呼ばれるので、元々そこまで遅くないんだと思う。

そのうちちゃんと書く。std::vectorのことはよくわかってないので、もしかしたらもっと高速化できるかも。