2

我有一个 sinatra 应用程序,它的执行速度比我想要的要慢得多。我的第一个怀疑是我自己的代码是瓶颈,所以我将它提取到一个独立的基准测试脚本中。

THREADS = 100
ITERATIONS = 1

def make_calls
  ITERATIONS.times do
 # ... my stuff here
 end
end

1.upto(THREADS) do |n|
  Benchmark.bm do |bm|
    threads = []
    n.times do
      threads << Thread.new { make_calls }
    end
    bm.report("#{n} threads:") { threads.each { |t| t.value } }
  end
end

make_calls 调用我自己的代码的地方。我很高兴地说,当我们达到 100 个线程时,所有线程中 make_calls 的累积时间是 0.6 秒,这对于我的目的来说已经足够快了。我在上面的线程中包装 make_calls 方法的原因是因为我自己的代码使用线程(通过 java.concurrent.FixedThreadPool(500) 的 java 本机线程)/ExecutorService,我想确保这在一个环境中表现良好可能使用其他线程模型。一旦 jruby 热身,单线程中的单次迭代将在大约 0.02 秒内运行。

所以上面是好的,但是当我将它添加到一个 sinatra web 服务器时:

require 'sinatra'
get '/' do
  # ... my stuff here
end

对此端点的请求的响应时间约为 0.5 秒 - 增加并发请求的数量,响应时间以线性方式上升。我已经使用了 jetty-rackup 和 trinidad 来尝试这个,在 linux 和 solaris 上都使用了 jruby 1.7。

我试图优化 trinidad 实例无济于事(最大/最小运行时间等)。我们看到的最佳性能是在线程安全中运行任一服务器!模式,并且两台服务器在此模式下都表现出比较的性能。

谁能向我解释时间消耗在哪里或如何改进此设置?

4

1 回答 1

0

听起来服务器并不是限制因素。也许这是 rack 或 Sinatra 的问题,但是

# ... my stuff here

并没有真正放弃太多。尝试使用分析工具(VisualVM可以开始使用)来检查您是否分配了大量不需要的对象,是否所有线程都在等待等,然后更改或消除您认为的瓶颈。

重复此操作,直到您认为它足够快;)

于 2013-05-20T13:46:13.650 回答