🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
STL

STL(Standard Template Library)は、ジェネティックコンテイナー、イテレーター、アルゴリズム、そして関数オブジェクトのC++ライブラリーです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2369閲覧

[コンテナクラス]vectorの要素に短い記述で高速にアクセスしたい。

Matt_

総合スコア1

STL

STL(Standard Template Library)は、ジェネティックコンテイナー、イテレーター、アルゴリズム、そして関数オブジェクトのC++ライブラリーです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/12/05 07:57

前提・実現したいこと

vectro.atを使用するより、ポインタを使って要素へアクセスした方が遥かに速いのですが、
at以外の方法で何か一行の記述で高速に要素にアクセスできる方法はないのでしょうか。
もし知っていたら共有していただけないでしょうか。

以上、よろしくお願いします。

該当のソースコード

#include <iostream> #include <vector> #include <time.h> using namespace std; const int NUM_ELEMENTS = 1000; const int NUM_ROOP = 100000; int main() { vector<int> vector_int_at(NUM_ELEMENTS); vector<int> vector_int_pointer(NUM_ELEMENTS); clock_t start = clock(); for (int j = 0; j < NUM_ROOP; j++) { for (int i = 0; i < NUM_ELEMENTS; i++) { vector_int_at.at(i) = 100;//atを使って配列にアクセス } } clock_t end = clock(); // 終了時間 std::cout << "duration = " << (double)(end - start) / CLOCKS_PER_SEC << "sec.\n"; start = clock(); for (int j = 0; j < NUM_ROOP; j++) { int* p = &vector_int_pointer[0]; for (int i = 0; i < NUM_ELEMENTS; i++) { *p= 100;//要素iを100にする p++;//次の配列に進む。 } } end = clock(); // 終了時間 std::cout << "duration = " << (double)(end - start) / CLOCKS_PER_SEC << "sec.\n"; return 0; }

出力結果

duration = 1.096sec.
duration = 0.16sec

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

at() はインデックスが有効かどうかの判定処理が入っている分、operator[] やポインタで直接アクセスするより遅くなります。
全部同じ値に埋めたいのであれば、std::fill() を使うのが一番はやいですが、そうでないランダムアクセスであれば、ポインタ経由のアクセスが最速となると思います。

手元で確認したところ、at() と operator[] やポインタで質問者さんの書かれているように4倍以上の差が出ませんでしたが、at() が一番遅いのは当然そうなるかと思います。

一行の記述で高速に要素にアクセスということであれば、[] 演算子によるアクセスでいいのではないでしょうか

benchmark name samples iterations estimated mean low mean high mean std dev low std dev high std dev ------------------------------------------------------------------------------- at() 100 1 6.55896 s 64.0391 ms 63.8582 ms 64.2244 ms 931.751 us 801.186 us 1.09331 ms operator[] 100 1 5.80973 s 57.4993 ms 57.3212 ms 57.6661 ms 881.166 us 768.317 us 1.02376 ms data() 100 1 3.21944 s 31.4387 ms 31.3449 ms 31.538 ms 493.85 us 447.879 us 581.101 us std::fill() 100 1 489.223 ms 5.27831 ms 5.2461 ms 5.31247 ms 168.613 us 158.597 us 181.088 us

Catch2 でベンチマークを取りました。

#define CATCH_CONFIG_MAIN #define CATCH_CONFIG_ENABLE_BENCHMARKING #include <catch2/catch.hpp> TEST_CASE("std::vector") { using namespace std; const int NUM_ELEMENTS = 1000; const int NUM_ROOP = 100000; vector<int> v(NUM_ELEMENTS); BENCHMARK("at()") { for (int j = 0; j < NUM_ROOP; j++) { for (int i = 0; i < NUM_ELEMENTS; i++) v.at(i) = 100; } }; BENCHMARK("operator[]") { for (int j = 0; j < NUM_ROOP; j++) { for (int i = 0; i < NUM_ELEMENTS; i++) v[i] = 100; } }; BENCHMARK("data()") { for (int j = 0; j < NUM_ROOP; j++) { int *p = v.data(); for (int i = 0; i < NUM_ELEMENTS; i++) { *p = 100; p++; } } }; BENCHMARK("std::fill()") { for (int j = 0; j < NUM_ROOP; j++) std::fill(v.begin(), v.end(), -1); }; }

投稿2020/12/05 08:11

編集2020/12/05 08:14
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Matt_

2020/12/05 08:29

ご丁寧にベンチマークを取っていただきありがとうございました。 試してみたところ、確かにoperatorを使った記述が速かったです。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問