忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2017/03/27 19:37 |
PHP5.4.7 PHPでarray_flatten関数のパフォーマンス測定の続き
前回の続き。

http://bloggdgd.blog28.fc2.com/blog-entry-278.html
http://bloggdgd.blog28.fc2.com/blog-entry-279.html
http://php.net/manual/ja/function.array-splice.php
http://php.net/manual/ja/function.array-merge.php
数々の証言によりarray_merge()よりarray_splice()のほうが早いのは確定的に明らかですが、では実際前回やった測定では何故array_splice()が異常に遅かったのかというお話。

http://bloggdgd.blog28.fc2.com/blog-entry-272.html
http://okwave.jp/qa/q8109749.html
私も全然気付いてなかったのですが、実はarray_flatten2()にはそもそも「フラット化できないことがある」というバグがありました。

ということで
> array_flatten3のarray_mergeをarray_spliceに書き換え
てみました。
<?php
	function array_flatten7($array) {
		$tmp = array();
		while (($val = array_shift($array)) !== null) {
			if (is_array($val)){
				array_splice($array, 0, 0, $val);
			}else{
				$tmp[] = $val;
			}
		}
		return $tmp;
	}
関数処理時間展開後の個数
array_flatten70.16667秒68228

array_splice()使ったこと無いからこの使い方が適切なのかはわかりませんが、想定通りarray_merge()より早くなりました。

んで、毎回array_shift()してからarray_splice()って意味ないよな、と少しだけ書き換えてみたのがこちら。
<?php
	function array_flatten8($array) {
		$tmp = array();
		$array = array_values($array);
		while (isset($array[0])){
			if (is_array($array[0])){
				array_splice($array, 0, 1, $array[0]);
			}else{
				$tmp[] = array_shift($array);
			}
		}
		return $tmp;
	}
関数処理時間展開後の個数
array_flatten80.14735秒68228

微妙に早くなりましたが、やはりarray_walk_recursive()には全然敵いませんね。
<?php
	function array_flatten9($array) {
		$array = array_values($array);
		$i=0;
		while (isset($array[$i])){
			if (is_array($array[$i])){
				array_splice($array, $i, 1, $array[$i]);
			}else{
				$i++;
			}
		}
		return $array;
	}
というかもうarray_shift()とか$tmpとか要らなくね、と思って上記のようにしてみたら、こちらは30秒を超える問題外の遅さでした。
原因は全くわかりませんが、array_flatten2()と同じような気がします。

さて、私の頭ではこれ以上の関数は思いつきませんでした。
再帰を使わずにより早く動作する手段は果たして見つかるでしょうか?

というかarray_flatten2()が遅かった原因は不明のままかよ。

関数処理時間展開後の個数
array_flatten5 (array_walk_recursive)0.06959秒68228
array_flatten1 (iterator_to_array+RecursiveIteratorIterator)0.08642秒68228
array_flatten6 (foreach+RecursiveIteratorIterator)0.11780秒68228
array_flatten8 (while (isset($array[0])))0.14735秒68228
array_flatten7 (array_shift+array_splice)0.16667秒68228
array_flatten3 (array_shift+array_merge)0.19846秒68228
array_flatten4 (再帰呼出し)0.32668秒68228
array_flatten2 (each)Maximum execution time of 30 seconds exceeded
array_flatten9 ($i++)Maximum execution time of 30 seconds exceeded


PR


2013/05/30 23:06 | Comments(0) | PHP

コメント

コメントを投稿する






Vodafone絵文字 i-mode絵文字 Ezweb絵文字 (絵文字)



<<デッドアイランド ZOTY脱出記 21日目 | HOME | Zend Framework2.2.0 Zend\Stdlib\SplStack / SplQueue>>
忍者ブログ[PR]