Cloud9でMysqlのスロークエリの確認

Cloud9環境でのMySqlのスロークエリの確認方法です。

以下ターミナルのBashからログファイルを作成しておきます。

masasikatano:~/workspace (master) $ touch slow_query.log
masasikatano:~/workspace (master) $ chmod 777 slow_query.log

MySqlからスロークエリ用の設定をします。

masasikatano:~/workspace (master) $ mysql -u root -pXXXXXXXXXX
mysql> set global slow_query_log=1;
mysql> set global long_query_time=1;
mysql> set global log_queries_not_using_indexes=1;
mysql> set global slow_query_log_file ='/home/ubuntu/workspace/slow_query.log';

これで、workspace上のslow_query.logからスローなクエリが確認できます。

Indexを追加するときと削除するときはこんなかんじ

 

# 追加
alter table users add index users_name_index (name);

# 削除
# ALTER TABLE users DROP INDEX users_name_index;

CODE COMPLETEを読みました – コードチューニング

前回と同様、コードコンプリート―完全なプログラミングを目指して (Microsoft PRESS) のまとめです。今回はコードチューニングに関して。

20年前の本なのですがコンピュータに関してのお約束というか基礎的な部分はほとんど変わっていないのでほとんどそのまま実用できると思います。

ループとスイッチング

for_if_test.php

<?php

print("悪い例の処理<br />");
$baseMemoryUsage = memory_get_usage();
$baseTime = microtime(true);

// 0 〜 10000000までを足す処理をする
$flag  = true; // 計算するかどうかのフラグ
$sum = 0;
for ($i = 0; $i < 10000000; $i++) {
    if($flag){
        $sum += $i;
    }
}

$maxMemoryUsage = (memory_get_peak_usage() - $baseMemoryUsage) / (1024 * 1024);
$processTime = microtime(true) - $baseTime;

printf("Max Memory Usage : %.3f [MB]<br />", $maxMemoryUsage);
printf("Process Time : %.2f [s]<br />", $processTime);
printf("Calculation result : %d <br />", $sum);


print("良い例の処理<br />");
$baseMemoryUsage = memory_get_usage();
$baseTime = microtime(true);

// 0 〜 10000000までを足す処理をする
$flag  = true; // 計算するかどうかのフラグ
if($flag){
    $sum = 0;
    for ($i = 0; $i < 10000000; $i++) {
        $sum += $i;
    }
}

$maxMemoryUsage = (memory_get_peak_usage() - $baseMemoryUsage) / (1024 * 1024);
$processTime = microtime(true) - $baseTime;

printf("Max Memory Usage : %.3f [MB]<br />", $maxMemoryUsage);
printf("Process Time : %.2f [s]<br />", $processTime);
printf("Calculation result : %d <br />", $sum);

これをCloud9のPHP環境で実行してみると、こんなかんじになります。

悪い例の処理
Max Memory Usage : 0.035 [MB]
Process Time : 1.88 [s]
Calculation result : 49999995000000
良い例の処理
Max Memory Usage : 0.034 [MB]
Process Time : 1.45 [s]
Calculation result : 49999995000000

ループと直接関係のない処理は、ループの外に積極的に出した方が高速化します。

ループの展開

for_unrolling_test.php

<?php

print("ループ展開前の処理<br />");
$baseMemoryUsage = memory_get_usage();
$baseTime = microtime(true);

// 0 〜 10000000までを足す処理をする
$sum = 0;
for ($i = 0; $i < 10000000; $i++) {
    $sum += $i;
}

$maxMemoryUsage = (memory_get_peak_usage() - $baseMemoryUsage) / (1024 * 1024);
$processTime = microtime(true) - $baseTime;

printf("Max Memory Usage : %.3f [MB]<br />", $maxMemoryUsage);
printf("Process Time : %.2f [s]<br />", $processTime);
printf("Calculation result : %d <br />", $sum);


print("ループ展開後の処理<br />");
$baseMemoryUsage = memory_get_usage();
$baseTime = microtime(true);

// 0 〜 10000000までを足す処理をする
$sum = 0;
for ($i = 0; $i < 10000000; $i+=5) {
    $sum += $i;
    $sum += $i + 1;
    $sum += $i + 2;
    $sum += $i + 3;
    $sum += $i + 4;
}

$maxMemoryUsage = (memory_get_peak_usage() - $baseMemoryUsage) / (1024 * 1024);
$processTime = microtime(true) - $baseTime;

printf("Max Memory Usage : %.3f [MB]<br />", $maxMemoryUsage);
printf("Process Time : %.2f [s]<br />", $processTime);
printf("Calculation result : %d <br />", $sum);

結果はこんなかんじです。

ループ展開前の処理
Max Memory Usage : 0.035 [MB]
Process Time : 4.51 [s]
Calculation result : 49999995000000 
ループ展開後の処理
Max Memory Usage : 0.034 [MB]
Process Time : 2.22 [s]
Calculation result : 49999995000000 

うおーループの展開超はええ

高速な言語で書き直す

PHPよりもC、Cよりもアセンブラ言語のように、ベースとなっている高速な言語を使用することでパフォーマンスが改善します。

この本ではPascalからアセンブラで書き直す例をあげているのですが、同じようにPHPからCを呼び出す方法をやってみます。

<?php

print("PHPでの処理<br />");
$baseMemoryUsage = memory_get_usage();
$baseTime = microtime(true);

// 0 〜 10000000までを足す処理をする
$sum = 0;
for ($i = 0; $i < 10000000; $i++) {
    $sum += $i;
}

$maxMemoryUsage = (memory_get_peak_usage() - $baseMemoryUsage) / (1024 * 1024);
$processTime = microtime(true) - $baseTime;

printf("Calculation result : %d <br />", $sum);
printf("Max Memory Usage : %.3f [MB]<br />", $maxMemoryUsage);
printf("Process Time : %.2f [s]<br />", $processTime);


print("PHPからC言語を呼び出しての処理<br />");
$baseMemoryUsage = memory_get_usage();
$baseTime = microtime(true);

$cmd = '/home/ubuntu/workspace/exec_test';
echo exec($cmd);

$maxMemoryUsage = (memory_get_peak_usage() - $baseMemoryUsage) / (1024 * 1024);
$processTime = microtime(true) - $baseTime;

printf("Max Memory Usage : %.3f [MB]<br />", $maxMemoryUsage);
printf("Process Time : %.2f [s]<br />", $processTime);

exec_test.c

#include <stdio.h>

int main(void) {

    int i = 0;
    long sum = 0;
    /* 0 〜 10000000までを足す処理をする */
    for (i = 0; i < 10000000; i++) {
        sum += i;
    }

    printf("Calculation result : %ld <br />", sum);

    return 0;
}

Cはコンパイルしておき、実行します。結果は、

PHPでの処理
Calculation result : 49999995000000
Max Memory Usage : 0.032 [MB]
Process Time : 1.52 [s]
PHPからC言語を呼び出しての処理
Calculation result : 49999995000000
Max Memory Usage : 0.031 [MB]
Process Time : 0.03 [s]

C言語がとんでもなく早いことがよくわかりました。

CODE COMPLETEを読みました – アナロジー

コードコンプリート―完全なプログラミングを目指して (Microsoft PRESS) を読んでみました。

かなり昔の本(初版1994年)で辞書くらい分厚いのもあってしばらく本棚に飾ってあったんですが読んでみたら現在でも使える内容満載のとっても良い本でした。おすすめ。

初っ端第一部からガツンときたのはアナロジーの話です。アナロジーとは例えばこんなの

抽象的でイメージしずらい数学や物理化学の現象をイメージしやすい身近なもので置き換えて理解しやすくすることです。

この本では以下の例え話をしています。

ソフトウェア ≒ 建築

仕様 ≒ 施工図

パッケージ ≒ ユニットパネルや備え付けの家具

さしずめ、プログラマはパネルや家具を集めて組み立て、人が立ち寄れる電脳商店を作る電脳大工さんといったところ。

プログラムとかソフトウェアってなんだか掴みどころが難しくイメージしずらい感じがするのがこのアナロジーですんなり頭に入るようになります。

身近なものに置き換えるって大事です。

Cloud9でバブルソート

いろいろ勉強したいことが溜まってきてしまっている今日このごろ、一個ずついろいろ試していきたいと思います。

とりあえず、HerokuGoogle App EngineならHerokuの方が無課金ユーザに優しい気がするのは分かった。

そんなわけで前からやってみたかったCloud9を使用してのC言語のバブルソートを書いてみます。

とりあえずC言語のコンパイル方法とかさっぱり忘れてしまっているのでドットインストールのC言語を見たり私の旧ブログを見たりして思い出します。

ほんでソースコード探検隊のバブルソートをやってみます。

C言語でバブルソート

bubble_sort.c

#include <stdio.h>

#define NUM_ITEMS 7

void bubbleSort(int numbers[], int array_size);
void printArray(int numbers[], int array_size);

int main()
{
  int numbers[NUM_ITEMS] = {6,5,3,1,7,2,4};

  printf("Start:\n");
  printArray(numbers, NUM_ITEMS);
  printf("\n");

  //perform bubble sort on array
  bubbleSort(numbers, NUM_ITEMS);

  printf("Done:\n");
  printArray(numbers, NUM_ITEMS);
  printf("\n");

  return 0;
}


void bubbleSort(int numbers[], int array_size)
{
  int i, j, temp;

  for (i = 0; i < (array_size - 1) ; i++) {
    for (j = (array_size - 1); j > i; j--) {
      printf("compare: %d and %d\n", numbers[j], numbers[j-1]);
      if (numbers[j-1] > numbers[j]) {
        temp = numbers[j-1];
        numbers[j-1] = numbers[j];
        numbers[j] = temp;

        printf("\tswap: ");
        printArray(numbers, array_size);
        printf("\n");
      }
    }
    printArray(numbers, array_size);
    printf("\n");
  }
}

void printArray(int numbers[], int array_size)
{
    int x;
    for (x = 0; x < array_size; x++) {
        printf("%d ", numbers[x]);
    }
}

コンパイルと実行

masasikatano:~/workspace $ gcc -o bubble_sort bubble_sort.c
masasikatano:~/workspace $ ./bubble_sort 
Start:
6 5 3 1 7 2 4 
compare: 4 and 2
compare: 2 and 7
        swap: 6 5 3 1 2 7 4 
compare: 2 and 1
compare: 1 and 3
        swap: 6 5 1 3 2 7 4 
compare: 1 and 5
        swap: 6 1 5 3 2 7 4 
compare: 1 and 6
        swap: 1 6 5 3 2 7 4 
1 6 5 3 2 7 4 
compare: 4 and 7
        swap: 1 6 5 3 2 4 7 
compare: 4 and 2
compare: 2 and 3
        swap: 1 6 5 2 3 4 7 
compare: 2 and 5
        swap: 1 6 2 5 3 4 7 
compare: 2 and 6
        swap: 1 2 6 5 3 4 7 
1 2 6 5 3 4 7 
compare: 7 and 4
compare: 4 and 3
compare: 3 and 5
        swap: 1 2 6 3 5 4 7 
compare: 3 and 6
        swap: 1 2 3 6 5 4 7 
1 2 3 6 5 4 7 
compare: 7 and 4
compare: 4 and 5
        swap: 1 2 3 6 4 5 7 
compare: 4 and 6
        swap: 1 2 3 4 6 5 7 
1 2 3 4 6 5 7 
compare: 7 and 5
compare: 5 and 6
        swap: 1 2 3 4 5 6 7 
1 2 3 4 5 6 7 
compare: 7 and 6
1 2 3 4 5 6 7 
Done:
1 2 3 4 5 6 7 
masasikatano:~/workspace $ 

ここであることに気づきます。

思ったよりC言語がしんどい。

というわけで、なんとなくPythonでも書いてみます。

Pythonでバブルソート

をやる前にCloud9でPythonを選択してワークスペースを作成すると、Python2がデフォルトになるためPython3に変更します。

masasikatano:~/workspace $ sudo mv /usr/bin/python /usr/bin/python2
masasikatano:~/workspace $ sudo ln -s /usr/bin/python3 /usr/bin/python
masasikatano:~/workspace $ python
Python 3.4.3 (default, Nov 17 2016, 01:08:31)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

OKです。↓のようなファイルを作成します。参考にしたのは、Problem Solving with Algorithms and Data Structures の バブルソート回です。

bubblesort.py

def bubbleSort(alist):                       # defで関数を定義
    for passnum in range(len(alist)-1,0,-1): # range()で8から-1ずつ進み0で終了を指定
        for i in range(passnum):
            if alist[i]>alist[i+1]:          # データ配列の前後を比較して前の数が大きい
                temp = alist[i]              # 一時変数に前のデータを格納
                alist[i] = alist[i+1]        # データ配列の前後を入れ替え
                alist[i+1] = temp

alist = [54,26,93,17,77,31,44,55,20] # ソートするデータの入った配列を定義
bubbleSort(alist)                    # 関数を実行
print(alist)                         # 表示

実行してみます。

masasikatano:~/workspace $ python bubblesort.py 
[17, 20, 26, 31, 44, 54, 55, 77, 93]
masasikatano:~/workspace $ 

うまくいきました。

やっぱPythonの方が楽だ・・

シェルに関しての基礎的な用語のまとめ

最近Linux関連の書籍をもりもり読んでいます。特に勉強になっているのは

HOW LINUX WORKS―Linuxの仕組み スーパーユーザが知っておくべきこと (MYCOM UNIX Books)ブライアン ウォード (著), Brian Ward (原著)

入門者のLinux 素朴な疑問を解消しながら学ぶ (ブルーバックス)奈佐原 顕郎 (著)

Linux 怒濤のQ&Aぱぱんだ (著)

という書籍達です。

そこで「シェル」というものに対してなんだか認識がふんわりしていることに気づいてしまったので折角なのでここにまとめておきます。

シェル / Shell

シェルとは、コンピュータのOS(オペレーティングシステム)を構成するソフトウェアの一つで、利用者からの操作の受け付けや、利用者への情報の提示などを担当するもの。

IT用語辞典 e-Words

 

このシェル(殻)という名前は、カーネル(OS)とアプリケーションの中間に位置し、カーネルを包み込むことに由来する。シェルは、ユーザーからのコマンドを対話的に処理するのみならず、シェルスクリプトと呼ばれるファイルを作成することにより、一連の処理をバッチ(一括して連続的に)実行することもできる。

@IT

bash

bashとは、多くのUNIX系OSで標準的に使われるシェル(ユーザからの操作を受け付け、結果を表示するソフトウェア)の一つ。

IT用語辞典 e-Words

シェルスクリプト

拡張子が.shでよく分からんおまじないからはじまるプログラムファイルのこと。

シェルスクリプトとはシェルが解釈できるコマンドを羅列したファイルのことである。
たとえばhelloworld.shというファイルを作成し以下のような内容を記述する。

#!/bin/bash
echo "Hello World !"
exit 0

snowlongの日記

 

実はなんだかよく分からない内に、「シェル」と「シェルスクリプト」を混同してしまっていたことに気づきました。こういう認識違いって怖いなあ。

 

tty

 

linusakesson.net

 

UNIXの仮想的なキャラクター端末のデバイス名

weblio辞書

ttyってドライバのことなのね。

PHPのベストプラクティス

PHPの(速さに関しての)良いコードに関しての情報を探しているのですが、色々と収穫があったのでここにまとめておきます。

PHPのプログラマ向けの雑誌や書籍を買ったり、Twitterで情報集めたり色々やってみたのですが、US英語 Googleで「PHP7 performance」とか「PHP7 best speed」とかで検索した方が一番良い情報が手に入るのでおすすめです。

ちなみに2017年6月現在、○○語Googleはほぼ、●●なSEO業者からの派遣社員で構成されていると確信できるようなメタメタな検索結果のため、滅多に使わなくなりました。

あ、でも最近では、『ブンドドってなんだ?』と思った時には使ったので●●業者から見向きもされないニッチなキーワードで検索すればそれなりに使えると思います。では本題。

PHP Best Practices

A short, practical guide for common and confusing PHP tasks

PHPコミッターのAlex Cabal氏のタイトル通りPHPのベストなプラクティス集が集められたサイト。私が特に目からウロコが落ちたのは、

・APCuを使おうぜ!-> php7でのインストール方法 -> Laravelでの使い方

・DateTimeクラス使おうぜ!

・NullやBooleanは===で評価しようぜ!

らへんです。

PHP 7 performance improvements

こちらもPHPのコントリビュータのJulien Pauli氏のPHPのパフォーマンスに関しての記事。

・配列のキーには数字を使うと早くなるよ!

なんて初めて知りましたぜ。

10 Things Not To Do In PHP 7

・PHPの終了タグは使用しないで!

・ループ内でDB参照しないで!

分かってるけど気を抜くとやってしまいかねないことです。

 

他にも見つけたら追記の予定。