2012-02-28 3 views
1

誰かは最近、これが悪いと言ってくれました自動的に最適化されませんか? Javaや他の言語では、私はと思うのですが、コンパイラーはキャッシング自体を実行するほどスマートです。変数のキャッシングは

はすなわち、この:

// myList is a List<String> 
String str = myList.get(0); 
String trimmed = str.trim(); 
String sub = str.substring(0, 5); 
boolean abc = str.startsWith("abc"); 

がこれよりも何より効率的ではありません:

String trimmed = myList.get(0).trim(); 
String sub = myList.get(0).substring(0, 5); 
boolean abc = myList.get(0).startsWith("abc"); 

コンパイラについての詳細を知っている誰も私にここにいくつかの洞察力を与えることはできますか? JavaScriptはそんなに愚かなのですか?それとも、Java /その他にも当てはまりますか?

+1

コンパイラは、関数を推測するのに十分な情報を純粋であるかもしれませんが(それに加えて、DOMに依存しないので、呼び出しの間にDOM操作が起こらないことなど、それは手を出ている)、実際にそれを試みる人はほとんどいません。 Javaコンパイラは意図的に愚かであり、JITコンパイラ(JavaとJSの両方)はコンパイル時により制約されます。彼らは通常、多くの分析を必要としない、最も有益な最適化に固執しています(例えば、仮想コールを投機的に取り除く、JSはいくつかの変数に静的タイプを仮定します)。 – delnan

+0

簡潔さを心配している場合は、jquery: '$("#myID ")の構文的な砂糖を使用してください。addClass(" a ")addClass(" b ")。addClass(" c ");' Soあなたのコードはこの変数を維持する必要はなく、より速くスコープから外れます。 –

+0

@bertはい、明らかに...それは単なるおもちゃの例でした。 –

答えて

4

$(el)は、比較的高価な関数呼び出しです。コンパイラは、呼び出しごとに常に同じ(または少なくとも同等の)オブジェクトを返すことを知ることができないため、提案する最適化を行うことはできません。

これは必ずしも言語の機能ではありません。私は、コンパイラが戻り値を推論し、この最適化を行うことができる言語(おそらくあなたが関数を冪等として宣言できるところ)があると確信しています。

私は、Javaコンパイラ/オプティマイザが比較的簡単なケースでそれを行うことができると確信しています。

同様の単純なケースでは、適切な状況でJa​​vascriptコンパイラがそれを実行してはならない理由はありません。しかし、コンパイルがブラウザで行われることを考慮する価値はあるので、ユーザーのブラウジングエクスペリエンスに影響を与えないように、最適化に費やすCPU時間の上限にはおそらく限界があります。

+0

あなたの答えのような音は "多分JSは最適化されますが、それに依存しません"。 –

+0

かなり良い概要です。シンプルなケースでも、それほど難しい作業をする準備ができてもいけない理由はありません。しかし、特にこのjQuery関数呼び出しでは、それが成功するかどうかは疑問です。 – dty

+0

もう1つ質問があります。コンパイラ関数のインライン展開は、この種の最適化を行う方法ですか?そうであれば、純粋な関数だけがインライン展開の候補になるのは本当ですか? –

1

あなたは、コンパイラが実際よりもスマートだと思います!

コンパイラは、APIの契約ではなく、言語の構文とセマンティクスを実際に知っていることに注意してください。したがって、$(el)が常に同じオブジェクトであることを知っているかもしれませんが、コンパイラはすべて、 "関数を引数elで呼び出す"ことを知っていますが、関数が同じ引数で同じ値を返すとは仮定できません。同様に、あなたのJavaの例から、myList.get(0)は常に同じオブジェクトになることがわかります(通常、何か他のことが起こらない限りですが、コンパイラはできません)。

だから、関数呼び出しから取得したオブジェクトへの参照を格納し、関数呼び出しを繰り返し行うのではなく、その参照で動作させるほうがはるかに効率的です。

関連する問題