From: takeru sasaki Date: 2008-06-02T16:50:42+09:00 Subject: [ruby-list:44995] Re: 重いタスクと平行にirbを使うと遅い? 佐々木です。 解決しました。 ext/readlineでHAVE_RL_EVENT_HOOKが無いと遅くなる問題が発生するようです。 OSX10.4のreadlineにはrl_event_hookが無かったので ./configure --prefix=/Users/takeru/ruby187_rl_fix --enable-pthread LDFLAGS="-L/opt/local/lib" CPPFLAGS="-I/opt/local/include" と指定してmacportで入れたreadlineにリンクしたら問題ありませんでした。 お騒がせしました。。。 #macportでrubyを入れた場合にmacportのreadlineにリンクしてくれれば親切ですね。 参考) http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb/ruby/ruby-list/7376?7376-7627 2008/06/02 14:44 takeru sasaki : > 佐々木です。 > > たびたびすみません。 > > どうやらirbではなく、readlineに原因がありそうというところまでわかりました。 > irbをreadlineを使わないようにしたら問題が起こらなくなりました。 > > readlineが入力待ち状態の時にスレッドの切替が少ないのかなあと思います。 > readlineにenterを押して入力するタイミングでは切替が発生してタスクが進んでいます。 > > > readlineとgetsを比較する再現コードです。 > --------------------------- > require "benchmark" > > def _t(s) > $stderr.puts(s) > end > $stdout.sync = true > > class Task > attr_reader :count > JOBS = 10000000 > def initialize(name) > @name = name > end > def run > @start = Time.now > puts "\n#{@name}:%s" % Benchmark.measure{ > @count = 0 > JOBS.times{ > @count += 1 > if @count%(JOBS/10)==0 > puts status > end > } > } > puts "task finished. @name=#{@name}" > end > def status > elapse = Time.now-@start > "name=#{@name} #{(100*@count/JOBS).to_i}% > speed=#{'%f'%(@count/elapse)} count=#{@count} elapse=#{elapse}" > end > end > > thread3 = Thread.start{ > $taskC = Task.new("C") > $taskC.run > } > if ARGV[0]=="readline" > require "readline" > while buf = Readline.readline("> ", true) > print "-> ", buf, "\n" > puts $taskC.status > end > elsif ARGV[0]=="gets" > while true > s = $stdin.gets > puts "gets -> #{s}" > puts $taskC.status > end > else > raise "ruby irb_slow.rb readline|gets" > end > --------------------------- > > > % ~/ruby187/bin/ruby -v irb_slow.rb readline > ruby 1.8.7 (2008-05-31 patchlevel 0) [i686-darwin8.11.1] >> > -> > name=C 0% speed=2643.992819 count=52040 elapse=19.682353 ★19秒後0% >> > -> > name=C 1% speed=3822.670383 count=136027 elapse=35.584287 ★35秒たっても1% >> ^C^Cirb_slow.rb:40: Interrupt > > % ~/ruby187/bin/ruby -v irb_slow.rb gets > ruby 1.8.7 (2008-05-31 patchlevel 0) [i686-darwin8.11.1] > name=C 10% speed=1002050.194698 count=1000000 elapse=0.997954 > name=C 20% speed=999638.630635 count=2000000 elapse=2.000723 > name=C 30% speed=1000346.453322 count=3000000 elapse=2.998961 > name=C 40% speed=999731.322207 count=4000000 elapse=4.001075 > name=C 50% speed=1000256.465758 count=5000000 elapse=4.998718 > name=C 60% speed=999587.170499 count=6000000 elapse=6.002478 > name=C 70% speed=999584.886676 count=7000000 elapse=7.002907 > name=C 80% speed=999357.288344 count=8000000 elapse=8.005145 > name=C 90% speed=999628.138333 count=9000000 elapse=9.003348 > name=C 100% speed=999338.837425 count=10000000 elapse=10.006616 > > C: 9.910000 0.040000 9.950000 ( 10.006724) > task finished. @name=C > > gets -> > name=C 100% speed=796855.353780 count=10000000 elapse=12.549329 > gets -> > name=C 100% speed=718121.663741 count=10000000 elapse=13.925217 ★13秒で100% > ^Cirb_slow.rb:46:in `gets': Interrupt > from irb_slow.rb:46 > >