2017-08-25 8 views
2

このコードを検討:議論されているスクリプトの場合PHP:メモリを大量に割り当てずに、短い文字列を長い文字列に挿入しますか?

$position = ... 
$data = substr($data, 0, $position) . $insertion . substr($data, $position); 

通常$dataは大きくない2-3よりMBです。しかし、スクリプトを使用したいユーザーを約17メガバイトのサイズで$dataのためにそれを使用しようとしたことが起こったとライン179は、上に示した第二1($data = ...)である

PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 17687776 bytes) in //index.php on line 179'

、33554432のバイトを得ました= 32 MBおよび17687776> 16 MB。今私は問題がメモリが$datasubstr($data, 0, $position)substr($data, $position)の両方に割り当てられていると仮定しています。私はthe memory limitを知っていて、それを増やそうと提案しました。しかし、メモリの制限が$dataより2倍以上大きくならないように最適化できるかどうかは疑問です。

私の質問です:メモリ使用量を最小限に抑えるために$insertionを挿入する巧妙な方法がありますか? ($dataをメモリに2回格納しない)substr($data, $position)が比較的小さいのはどうですか?

答えて

3

現在の実装は、ターゲットの位置に依存します。データの終わりに近い位置であれば、メモリ効率が最も高くなります。最悪の場合はデータの先頭に挿入されます。例えば

ミニベンチマーク:ショーのピーク使用上の

$data  = str_repeat('abcde', 500000); 
$insertion = 'abc'; 
$position = 0; 

$data = substr($data, 0, $position) . $insertion . substr($data, $position); 

echo memory_get_peak_usage(), "\n"; 

スクリプトは、(私のマシン上)7868728バイトです。

:私は $position = strlen($data)/2を設定した場合のデータの終わり( $position = strlen($data))に文字列を追加する場合、それはそれが5365720.

(またdepends PHPバージョンに上記のコードのメモリ消費更新)を印刷6619424.を印刷しますsubstr_replace():文字列の一部を置き換えるため

しかし、PHPはすでに効率的な機能を持っているすべての場合において

$data = substr_replace($data, $insertion, $position, 0); 

、これが必要です上記の実装と同じくらい多くのメモリ(substr()の結果を連結したもの)が最良の場合です。

+0

これは確かに、特に(memory_get_peak_usage()を使って)テストする方法に非常に役立ちますが、私はテストのいくつかの議論の結果を得ました。正しい(実際には、私は*なぜ*を探していて、より詳細な画像を得なければならない)。間違いなくupvoted。 – YakovL

+1

ああ、そうですよ! https://3v4l.org/UV3Is - この場合のメモリ消費量は、PHPのバージョンによって異なります(最新のバージョンでは、いくつかの関連する最適化があるかもしれません)。ありがとう、私は答えを編集しました。 – Timurib

関連する問題