Help us understand the problem. What is going on with this article?

node.js にとても長い式を食べさせると死ぬ

More than 1 year has passed since last update.

のシリーズ。

整数を419378回インクリメントするとMacのg++が死ぬ

C++でアスタリスクをつけすぎると端末が落ちる
にインスパイアされて。

node.js に

  • (((((1)))))
  • [[[[[1]]]]]
  • 1+1-1+1-1+1-1+1-1+1-1
  • !!!!!1
  • {0:{0:{0:{0:{0:1}}}}}
  • function(){ return function(){ return 1; }() }()

のような式を食べさせていつ死ぬのか調べてみた。

node は v9.6.1 。
環境は、 macOS High Sierra。メモリ 16GB。

結果。

(((((1)))))

ruby2.5
a = [*1..20000]
p(a.bsearch do  |n|
  puts "#{n}"
  File.open( "hoge.js", "w" ){ |f| f.puts( "console.log("+"("*n+"1"+")"*n+")" ) }
  begin
    "1"!=%x( node hoge.js ).strip
  rescue
    true
  end
end)
#=>690
# RangeError: Maximum call stack size exceeded

なんか node.js はしぶといんじゃないかと先入観を持っていたんだけど、 ruby と比べるとだいぶ弱かった。
python よりは強いけど。

[[[[[1]]]]]

ruby2.5
a = [*1..20000]
p(a.bsearch do  |n|
  puts "#{n}"
  File.open( "hoge.js", "w" ){ |f| f.puts( "console.log("+"["*n+"1"+"]"*n+")" ) }
  begin
    !(/^[\[\s]+(1|Array)[\]\s]+$/===%x( node hoge.js ).strip)
  rescue
    true
  end
end)
#=> 767
# RangeError: Maximum call stack size exceeded

( ) よりも [ ] の方が長持ちした。意外。
[ ] の方が重そうだけど。

1+1-1+1-1+1-1+1-1+1-1

これは、「+1-1」の個数が 1億個でも死ななかった。
しぶとい。

!!!!!1

ruby2.5
a = [*1..1000000]
p(a.bsearch do  |n|
  puts "#{n}"
  File.open( "hoge.js", "w" ){ |f| f.puts( "console.log("+"!"*n+"1)" ) }
  begin
    !(/true|false/===%x( node hoge.js ).strip)
  rescue
    true
  end
end)
#=> 6204
# RangeError: Maximum call stack size exceeded

括弧と比べるとだいぶしぶとい。10倍ぐらいの感じ。

{0:{0:{0:{0:{0:1}}}}}

ruby2.5
a = [*1..20000]
p(a.bsearch do  |n|
  puts "#{n}"
  File.open( "hoge.js", "w" ){ |f| f.puts( "console.log("+"{0:"*n+"1"+"}"*n+")" ) }
  begin
    ""==%x( node hoge.js ).strip
  rescue
    true
  end
end)
#=>647
# RangeError: Maximum call stack size exceeded

オブジェクトのネストは、括弧と同じぐらいになった。
なんとなく、括弧の半分ぐらいと予想していたんだけど、ハズレた。

function(){ return function(){ return 1; }() }()

ruby2.5
a = [*1..1000000]
p(a.bsearch do  |n|
  puts "#{n}"
  File.open( "hoge.js", "w" ){ |f| f.puts( "console.log("+"function(){ return "*n+"1;" + "}()"*n + ")" ) }
  begin
    "1"!=%x( node hoge.js ).strip
  rescue
    true
  end
end)
#=> 375
# RangeError: Maximum call stack size exceeded

関数呼び出しのネストの重さは、括弧の倍ぐらいということなんだろう。
もっと重さに差があるものと想像していた。

まとめ

node.js は、おおむね ruby よりは弱く、python よりは強い感じ。
ただ、「1+1-1+1-1 ... +1-1」に関しては、メモリの許す限りいくらでも行けそうな雰囲気である。

ブラウザでどうなるのかが気になるところだけど、手軽に試す方法がよくわからないのでやめておく。

根拠のない予想としては、 Firefox の圧勝で、次が Chrome、そして Opera、 Edge、 Safari の順かな。

Nabetani
横浜へなちょこプログラミング勉強会をやっていました。 / CodeIQ の出題者でした。 / 日経 WinPC に連載を持っていました(名義が違うけど) / Yokohama rb に半分ぐらい参加しています。 / twitter : http://twitter.com/Nabetani
https://nabetani.hatenadiary.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away