6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

不発弾Advent Calendar 2018

Day 2

ちょっとしたテクリで速度改善Tips

Last updated at Posted at 2018-12-30

C, C++(他も?)の話

インクリメント、デクリメント

一般的な書き方

int i = 1;
i++;

このようなインクリメントを後置くインクリメントと言います。
for文を使う場合

for(int i = 0;i < 10000;i++){
}

ちょっとだけ速くなる書き方

int i = 1;
++i

このようなインクリメントを前置インクリメントと言います。

for文を使う場合

for(int i = 0;i < 10000;++i){
}

ちょこっと解説

後置インクリメントだと内部でインスタンスの生成が発生するので、ちょっと処理に時間がかかるようです。ただ現在ではコンパイラの発達により、どちらでもほとんどが出ないことが多いです

参考

C, C++他多数の言語での話

2倍の書き方

一般的な書き方

int num = 100;
int twice = num * 2;

ちょっとだけ速くなる書き方

int num = 100;
int twice = num << 1;

ちょこっと解説

ビット演算した方が速い」と一般的によく言われるが、実際どのような場合にビット演算を使うのかピンとこない場合が多いと思います。そんなとき最もよく使いやすいケースが上記の2倍のケースではないだろうか?
ただし、初見では???となることが多い(可読性が下がる)ので使い所は考えた方がいいかもしれません。

※ 右シフト(num >> 1, 半分, 1/2)は符号付き(負の値)での計算において、 num / 2num >> 1 で実行結果が変わることがあります。

参考

Listの話

一般的な書き方

List<int> numList = new List<int>();
for(int i = 0;i < 10000;++i){
  numList.Add(i);
}
if(numList.Contain(9999)){
}

ちょっとだけ速くなる書き方

HashSet<int> numList = new HashSet<int>();
for(int i = 0;i < 10000;++i){
  numList.Add(i);
}
if(numList.Contain(9999)){
}

ちょこっと解説

C#やJavaなどのList(C++だとVector)にあたるような可変長配列を用いる場合、その配列の中に値が存在するかどうか判定する処理を書くと以下のような処理と同等の処理が行われます。

public bool Contain(int value){
  for(int i = 0;i < this.Count;i++){
    if(this[i] == value){
      return true;
    }
  }
  return false;
}

例えば、このListの中にデータが10000件ある場合、最大10000回のチェックをすることになります。(このような処理を線形探索といいます)
HashSetやDictionary(JavaではHashMapなど)を用いた場合、1回の処理で、該当の値を取得することができます。そのため判定も1回だけになるので速度が速くなります。(このような処理をハッシュ探索といいます。詳しくは参考などをご覧下さい。

参考

MySQLの話

last

一般的な書き方

SELECT id FROM テーブル名 ORDER BY DESC LIMIT 1;

よく使われるRailsで行う場合

ActiveRecord.last.id

超速くなる書き方

SELECT (information_schema.tables.AUTO_INCREMENT - 1) FROM information_schema.tables WHERE information_schema.tables.TABLE_NAME = 'テーブル名';

注意点

ちょこっと解説

SQLでORDER BY文を発行するとたとえLIMIT 1であっても、件数が増えれば処理が遅くなります。(基本的にソート処理は重たい)
MySQLにはINFORMATION_SCHEMAというテーブル情報など、MySQL内において各種定義値などのメタ情報を記録しているテーブルがデフォルトで存在します。このINFORMATION_SCHEMAテーブルからは読み込みのみ可能で、SELECT文を用いることで値を取得することができます。INFORMATION_SCHEMAのテーブルの情報にはそのテーブルの件数(TABLE_ROWS)や末尾の情報(AUTO_INCREMENT)の情報も記録されています。そこで、このテーブルから情報を取得することで高速に実行することができます。
※ ただし注意点もあることも忘れずに。

その他

他にもちょっと書き方を変えるだけで速度が改善できるようんケースがあれば追記していきたいと思います。

6
6
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?