読者です 読者をやめる 読者になる 読者になる

記述方法による性能改善について

javascript

ハイライトを作るついでにベンチマークをとりつつ、どういう書き方が速いのか調べていました。javascriptはわりとひどいと思います。しかたないけど。
例えば、

  • for (var i = 0; i = array.length; ++i) より for (var i = 0, len = array.length; i < len; ++i)と書いたほうが速い

とか、

  • というか変数やそのプロパティやメソッドへのアクセスで毎回記号表の検索が発生しているっぽいので、ループ内では変数のキャッシュを使ったほうが速い

とか。このあたりはCなんかでメンバ変数がコンパイル時に構造体のアドレスとそこからのオフセット値に変換されている感覚とは違っています。va.vb.vc.vd.dataと階層が増えると階層分の検索が必要なのでものすんごい回数のループ内では速度にだいぶ影響するようです。メンバを好き勝手増やせる言語だから普通に仕方ないとは思います。
そして、

  • object.method()形式で呼び出さないとメソッド内でのthisが変化するので、そこはどうしようもねえ

となるので、どうせJavaScript自体遅いし、アルゴリズムをもう改善できないところでもっていけば、細かいところはあまり気にしなくてもいいと思います。仕事でどうしてももっと速くしろ言われたらもうなんかC++で超速いCOMとか作って、ActiveXObjectから呼び出せばええやんと思います。かっこよく独自のツールーバーとかにしたらいいです。キレます。あがああ。
正規表現はかなり速いみたいです。配列のpush、pop、shift、unshiftはカウンタを使って自分でやったほうが速いです。サイズ変更処理がないからだと思います。普通ですが。
あと、innerHTMLとDOM APIどっちか速いとかの話は興味あるところですが、innerHTMLが速い説はたぶんうそだ! 勘ですが。たぶん代入時にはこのへん再構築が必要ですよフラグと再構築チェックイベントをキューに突っ込んでいるだけで、HTMLのパーズからノードの再構築処理は、同じ関数内でDOM APIが使われたときか、または関数から抜けたあとに実行されていて、描画処理はきっと関数から抜けた後だから、ベンチマークがまともに測れていないのでは? と思っています。非同期なんですよ。本当にinnerHTMLのほうが速かったらなら、javascriptの代入処理と関数呼び出しはどんだけ遅いんだよ、とキレます。また性能とは別の話で、innerHTMLはタグのアトリビュートに入れる文字列の"e;などの実体参照が戻されるから二重にエスケープとしていないとサーバサイドでエスケープしたダブルクォートなどが復活してしまってセキュリティーホールになったりしそうだしアレなので、あまり使わないほうがいいと思います。ということでDOM APIなんです。なんかかっこいいし。
個人的まとめしては「速度よりもIEがメモリリークしていないことに気を使ったほうがいい」です。ぜんぜん関係のない話ですが。最近気づいてショックなんです。