金利0無利息キャッシング – キャッシングできます

 | 

2012-10-12

evalとnew Functionはちょっとだけ意味が違う

14:01 | evalとnew Functionはちょっとだけ意味が違う  - 金利0無利息キャッシング – キャッシングできます を含むブックマーク はてなブックマーク - evalとnew Functionはちょっとだけ意味が違う  - 金利0無利息キャッシング – キャッシングできます

https://github.com/felixge/faster-than-c がちょっと話題になってたので

取り上げられてる最適化コードの部分が要約すると「eval使って動的に最適化されたコード生成すると速い」みたいになるんだけど、正確にはevalじゃなくてnew Functionを使っていて、evalとnew Functionには違いがある。new Functionと違って、evalは呼び出した箇所のcontextで実行される。なので例えばevalするコードをevalしておくと、過去に遡ってevalできるので便利。

var env_history = [];
var save_env = "env_history.unshift([function(code){return eval(code)}, arguments])";
function back(num){
    return {
        eval: env_history[num][0],
        arguments: env_history[num][1]
    }
}

function hoge(p){
    eval(save_env);
    var a = "hoge " + p;
}

hoge(12345);
hoge(2345);


// take me back
a = back(0).eval("a")
b = back(1).eval("a")

逆に言うと、evalで動的に生成された関数がクロージャになっていて、evalを呼び出した箇所のcontextを維持しなくてはいけないような状況が発生するとメモリリークが発生してしまう。なので、こういうおかしなことをする必要がなく、"単純に"文字列から関数を動的に生成したいだけなら、new Functionを使うべき。もちろん、多くの場合はそういうことをやる必要自体がない。

ループ展開済みのコードをnew Functionで生成しておくというのは割とよく知られている(と思う)テクニックで、evalやnew Function自体はとても遅い。処理系によってはevalのほうが速かったりするんだけど、どうせこれは一回きりなので、あんまり気にする必要がない。eval使う必然性がないならnew Functionを使ったほうが良いと思います。

CemreCemre2012/10/26 18:18Surprising to think of smeothing like that

hphhwkdjrhphhwkdjr2012/10/27 01:05ABQjzu <a href="http://frlhmxbwlqmg.com/">frlhmxbwlqmg</a>

nytduurhudvnytduurhudv2012/10/29 07:10oKEhHQ <a href="http://qtebncdmwxll.com/">qtebncdmwxll</a>

rydwpobbrydwpobb2012/10/29 11:533zv73Y , [url=http://rgxsqzwundue.com/]rgxsqzwundue[/url], [link=http://aspzcqlpqxaf.com/]aspzcqlpqxaf[/link], http://bpqedvlxkrfh.com/

トラックバック - http://subtech.g.hatena.ne.jp/mala/20121012
 |