_onichannn

【PHP】in_array()での重複チェックと添字直アクセスのスピード比較。

例えばループ処理中重複した値を弾きたい場合、下記2つのアプローチではどちらが高速なのだろうか。

1, キャッシュ配列に値を詰め込みその後、in_array()を用いて重複値をチェックする
2, 値を配列のキーに持たせ、isset()にて添字の存在チェックい重複を弾く

結果は以下のとおり。

$cache = array();
$start = microtime(true);
for($i = 0; $i < 10000; $i++) {
	$md5 = md5($i);
	if(!in_array($md5, $cache)) {
		$cache[] = $md5;
	}
}
$end = microtime(true);

echo $end - $start."\n";


$cache = array();
$start = microtime(true);
for($i = 0; $i < 10000; $i++) {
	$md5 = md5($i);
	if(!isset($cache[$md5])) {
		$cache[$md5] = true;
	}
}
$end = microtime(true);

echo $end - $start."\n";

上はin_array()、下はisset()

5.5056478977203
0.020223140716553

その差は272倍。
圧倒的に添字アクセスの方が速い。

 

【PHP】file_get_contents()関数でコンテンツ取得時のHTTP レスポンスヘッダを取得する。

メモ。

file_get_contents()関数を実行した直後に$http_response_header変数をダンプするとHTTPレスポンスヘッダを取得することが出来る。

file_get_contents('http://example.com');
var_dump($http_response_header);

↓

array(9) {
  [0]=>
  string(15) "HTTP/1.1 200 OK"
  [1]=>
  string(35) "Date: Sat, 18 Jan 2014 08:34:35 GMT"
  [2]=>
  string(31) "Server: Plack::Handler::Starlet"
  [3]=>
  string(37) "Content-Type: text/xml; charset=utf-8"
  [4]=>
  string(32) "Vary: User-Agent,Accept-Encoding"
  [5]=>
  string(20) "X-Framework: JP/4.01"
  [6]=>
  string(98) "Set-Cookie: ldblog_u=121.107.203.110.1390034075591149; path=/; expires=Fri, 18-Apr-14 08:34:35 GMT"
  [7]=>
  string(45) "P3P: CP="BUS OUR PHY STP ADM CUR DEV PSA PSD""
  [8]=>
  string(17) "Connection: close"
}

 

【PHP】SimpleXMLでCDATAを取得する。

通常であればCDATA内の情報は破棄されてしまうが、第2引数、第3引数を下記のようにしてやることで、情報を正しく取得することが出来る。

simplexml_load_file('http://example.com', 'SimpleXMLElement', LIBXML_NOCDATA);

 

【Linux】topコマンドの「load average」に関するめも。

・リアルタイムでシステムの状況を把握したい場合は「top」コマンド
・長期間に及ぶシステム負荷の傾向を掴みたい場合は「sar」コマンド
・load averageはCPUの処理を待っているタスクの数を表す
・値が0に近づくほど、待タスクの数が少ない
・値が大きいほど処理待のタスクが多く、サーバーのレスポンスが遅くなる
・左から1分、5分、15分間の平均値を表示している
・左の値が大きくなっていれば、直近の処理で高負荷がかかっていることがわかる

 

【CakePHP2.4】saveAll()メソッドでINSERT文を分割させたくない場合。

AppModelに下記独自関数を定義する。


App::uses('Sanitize', 'Utility');

class AppModel extends Model {
	
	public function saveAllAtOnce($data) {
		if(count($data) > 0 && !empty($data[0])) {
			$data = Sanitize::clean($data);
			$value_array = array();
			$fields = array_keys($data[0][$this->name]);
			foreach ($data as $key => $value) {
				$value_array[] = "('" . implode('\',\'', $value[$this->name]) . "')";
			}
			$sql = "INSERT INTO " . $this->table . " (" . implode(', ', $fields) . ") VALUES " . implode(',', $value_array);
			$this->query($sql);
			return true;
		}
		return false;
	}
	
}

この関数に下記のような構造のデータを渡せば、一度のインサート文で複数レコードを一括登録してくれるのでsaveAll()メソッドを使うよりも処理が速くなる。

array(
	0 => array(
		'ModelName' => array(
			'Field1' => 'value',
			'Field2' => 'value',
			'Field3' => 'value',
			'Field4' => 'value',	
		)
	),
	1 => array(
		'ModelName' => array(
			'Field1' => 'value',
			'Field2' => 'value',
			'Field3' => 'value',
			'Field4' => 'value',
		)
	)	
)

これはかなり便利。

 

【PHP】現在のメモリ使用量を取得する。

めも。

// メモリの使用量をバイト単位で取得する
echo memory_get_usage();

// PHPに割り当てられたメモリの最大値を得る
echo memory_get_peak_usage();

メモリを気にする重たい処理を作ってるとよく使う。

 

【Excel】列、または行全体を参照する方法。

めも。

関数で行全体や、列全体を参照したい場合、下記のように範囲を指定してやればよい。

※列全体の合計を求めたい場合。

=SUM(A:A)

※行全体の合計を求めたい場合。

=SUM(1:1)

 

【PHP】アルファベット記号を用いた26進数を生成する。

Excelの列番号を取得したくてやった時のメモ。

function getColKey($target) {
	for($i = 0; $i < 26; $i++){
		$alphabet[] = strtoupper(chr(ord('a') + $i));
	}
	$one = fmod($target, 26);
	$result = $alphabet[$one];
	$carry = ($target - $one) / 26;
	while($carry != 0) {
		$one = fmod($carry - 1, 26);
		$result = $alphabet[$one].$result;
		$carry = ($carry - 1 - $one) / 26;
	}
	return $result;
}

関数に数値を渡せばその番号目の列キーが帰ってくる。

下記例。

echo getColKey(24)."\n";
echo getColKey(235)."\n";
echo getColKey(2146)."\n";
echo getColKey(13461)."\n";

↓

Y
IB
CDO
SWT