72

Java や C# などの言語では、文字列は不変であり、一度に 1 文字ずつ文字列を作成すると計算コストが高くなる可能性があります。System.Text.StringBuilder上記の言語には、C#や Javaなど、このコストを削減するためのライブラリ クラスがありますjava.lang.StringBuilder

php (4 または 5; 私は両方に興味があります) はこの制限を共有していますか? もしそうなら、利用可能な問題に対する同様の解決策はありますか?

4

12 に答える 12

63

いいえ、文字列は変更可能であるため、PHP には stringbuilder クラスの型はありません。

そうは言っても、何をしているかに応じて、文字列を構築するさまざまな方法があります。

たとえば、echo は、出力用にカンマ区切りのトークンを受け入れます。

// This...
echo 'one', 'two';

// Is the same as this
echo 'one';
echo 'two';

これが意味することは、実際に連結を使用せずに複雑な文字列を出力できるということです。これは遅くなります。

// This...
echo 'one', 'two';

// Is faster than this...
echo 'one' . 'two';

この出力を変数に取り込む必要がある場合は、出力バッファリング関数を使用して実行できます。

また、PHP の配列パフォーマンスは非常に優れています。コンマで区切られた値のリストのようなことをしたい場合は、単に implode() を使用してください

$values = array( 'one', 'two', 'three' );
$valueList = implode( ', ', $values );

最後に、 PHP の文字列型とそのさまざまな区切り文字、およびそれぞれの意味についてよく理解しておいてください。

于 2008-09-23T21:47:50.403 に答える
16

StringBuilder アナログは PHP では必要ありません。

簡単なテストをいくつか行いました。

PHPで:

$iterations = 10000;
$stringToAppend = 'TESTSTR';
$timer = new Timer(); // based on microtime()
$s = '';
for($i = 0; $i < $iterations; $i++)
{
    $s .= ($i . $stringToAppend);
}
$timer->VarDumpCurrentTimerValue();

$timer->Restart();

// Used purlogic's implementation.
// I tried other implementations, but they are not faster
$sb = new StringBuilder(); 

for($i = 0; $i < $iterations; $i++)
{
    $sb->append($i);
    $sb->append($stringToAppend);
}
$ss = $sb->toString();
$timer->VarDumpCurrentTimerValue();

C# (.NET 4.0):

const int iterations = 10000;
const string stringToAppend = "TESTSTR";
string s = "";
var timer = new Timer(); // based on StopWatch

for(int i = 0; i < iterations; i++)
{
    s += (i + stringToAppend);
}

timer.ShowCurrentTimerValue();

timer.Restart();

var sb = new StringBuilder();

for(int i = 0; i < iterations; i++)
{
    sb.Append(i);
    sb.Append(stringToAppend);
}

string ss = sb.ToString();

timer.ShowCurrentTimerValue();

結果:

10000 回の反復:
1) PHP、通常の連結: ~6ms
2) PHP、StringBuilder を使用: ~5 ms
3) C#、通常の連結: ~520ms
4) C#、StringBuilder を使用: ~1ms

100000 回の反復:
1) PHP、通常の連結: ~63ms
2) PHP、StringBuilder を使用: ~555ms
3) C#、通常の連結: ~91000ms // !!!
4) C#、StringBuilder を使用: ~17ms

于 2013-04-19T20:17:16.230 に答える
12

時限比較を行う場合、違いは非常に小さいため、あまり関連性がありません。コードを読みやすく、理解しやすくするための選択を行うと、さらに効果的です。

于 2008-09-23T23:08:42.283 に答える
10

私はあなたが話していることを知っています。Java StringBuilder クラスをエミュレートするために、この単純なクラスを作成しました。

class StringBuilder {

  private $str = array();

  public function __construct() { }

  public function append($str) {
    $this->str[] = $str;
  }

  public function toString() {
    return implode($this->str);
  }

}
于 2010-08-17T02:32:14.443 に答える
6

PHP 文字列は可変です。次のように特定の文字を変更できます。

$string = 'abc';
$string[2] = 'a'; // $string equals 'aba'
$string[3] = 'd'; // $string equals 'abad'
$string[5] = 'e'; // $string equals 'abad e' (fills character(s) in between with spaces)

そして、次のように文字列に文字を追加できます。

$string .= 'a';
于 2008-09-23T21:48:52.023 に答える
2

はい。彼らはそうします。たとえば、いくつかの文字列を一緒にエコーしたい場合は、次を使用します

エコー str1,str2,str3

それ以外の

エコー str1.str2.str3
それを少し速くするために。

于 2008-09-23T21:43:03.457 に答える
1

まず、文字列を連結する必要がない場合は、連結しないでください。連結した方が常に速くなります。

echo $a,$b,$c;

よりも

echo $a . $b . $c;

ただし、少なくとも PHP5 では、特に特定の文字列への参照が 1 つしかない場合、文字列の連結は非常に高速です。インタプリタはStringBuilder内部で -like テクニックを使用していると思います。

于 2008-09-23T22:03:39.803 に答える
0

PHP文字列内に変数値を配置している場合、インライン変数インクルードを使用する方が少し速いことを理解しています(それは正式な名前ではありません-何であるか思い出せません)

$aString = 'oranges';
$compareString = "comparing apples to {$aString}!";
echo $compareString
   comparing apples to oranges!

機能するには、二重引用符で囲む必要があります。配列メンバーに対しても機能します (つまり

echo "You requested page id {$_POST['id']}";

)

于 2008-09-23T22:20:05.020 に答える
-4

PHP にはそのような制限はありません。php は strng を dot(.) 演算子で連結できます。

$a="hello ";
$b="world";
echo $a.$b;

「ハローワールド」を出力します

于 2008-09-23T21:42:55.080 に答える