我正在 scala play 框架 2.5 和 golang 中对一个简单的 hello world 示例进行基准测试。 Golang 的表现似乎远远落后于 play,我想知道如何优化 play 框架以提高性能。 我正在使用以下内容进行基准测试
ab -r -k -n 100000 -c 100 http://localhost:9000/
我在项目的所有地方都使用默认配置以生产模式运行 play 2.5。有人可以帮我调整 Play 服务器的性能以获得最佳性能吗?我阅读了默认调度程序线程池,但我不确定要为我的电脑使用什么设置。还有其他我可以检查的有助于提高性能的区域吗?
这是我的行军规范
Intel(R) Xeon(R) W3670 @ 3.20GHz 3.19GHz, 12.0 GM RAM, running windows 7 64-bit
请注意,我正在使用 sbt(clean 和 stage)在 prod 模式下就地运行服务器并执行在 target/universal/stage/bin/中找到的 bat 文件。这是 Play 的源代码
package controllers
import play.api.mvc._
class Application extends Controller {
def index = Action {
Ok("Hello, world!")
}
}
这是 ab 基准测试的结果
ab -r -k -n 100000 -c 100 http://localhost:9000/
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests
Server Software:
Server Hostname: localhost
Server Port: 9000
Document Path: /
Document Length: 13 bytes
Concurrency Level: 100
Time taken for tests: 1.537 seconds
Complete requests: 100000
Failed requests: 0
Keep-Alive requests: 100000
Total transferred: 15400000 bytes
HTML transferred: 1300000 bytes
Requests per second: 65061.81 [#/sec] (mean)
Time per request: 1.537 [ms] (mean)
Time per request: 0.015 [ms] (mean, across all concurrent requests)
Transfer rate: 9784.69 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 1
Processing: 0 2 1.9 1 72
Waiting: 0 2 1.9 1 72
Total: 0 2 1.9 1 72
Percentage of the requests served within a certain time (ms)
50% 1
66% 2
75% 2
80% 2
90% 3
95% 3
98% 5
99% 8
100% 72 (longest request)
这是golang的源码
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, world!")
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
这是 golang 的 ab 基准测试的结果
ab -r -k -n 100000 -c 100 http://localhost:8080/
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests
Server Software:
Server Hostname: localhost
Server Port: 8080
Document Path: /
Document Length: 13 bytes
Concurrency Level: 100
Time taken for tests: 0.914 seconds
Complete requests: 100000
Failed requests: 0
Keep-Alive requests: 100000
Total transferred: 15400000 bytes
HTML transferred: 1300000 bytes
Requests per second: 109398.30 [#/sec] (mean)
Time per request: 0.914 [ms] (mean)
Time per request: 0.009 [ms] (mean, across all concurrent requests)
Transfer rate: 16452.48 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 1
Processing: 0 1 1.5 1 52
Waiting: 0 1 1.5 1 52
Total: 0 1 1.5 1 52
Percentage of the requests served within a certain time (ms)
50% 1
66% 1
75% 1
80% 1
90% 1
95% 2
98% 5
99% 7
100% 52 (longest request)
先谢谢你 弗朗西斯
更新!
以下结果提高了性能,但我仍然对可以提高性能的其他想法感兴趣
package controllers
import play.api.mvc._
import scala.concurrent.Future
import play.api.libs.concurrent.Execution.Implicits.defaultContext
class Application extends Controller {
def index = Action.async {
Future.successful(Ok("Hello, world!"))
}
}
基准测试结果
ab -r -k -n 100000 -c 100 http://localhost:9000/
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests
Server Software:
Server Hostname: localhost
Server Port: 9000
Document Path: /
Document Length: 13 bytes
Concurrency Level: 100
Time taken for tests: 1.230 seconds
Complete requests: 100000
Failed requests: 0
Keep-Alive requests: 100000
Total transferred: 15400000 bytes
HTML transferred: 1300000 bytes
Requests per second: 81292.68 [#/sec] (mean)
Time per request: 1.230 [ms] (mean)
Time per request: 0.012 [ms] (mean, across all concurrent requests)
Transfer rate: 12225.66 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 1
Processing: 0 1 2.2 1 131
Waiting: 0 1 2.2 1 131
Total: 0 1 2.2 1 131
Percentage of the requests served within a certain time (ms)
50% 1
66% 1
75% 1
80% 2
90% 2
95% 3
98% 5
99% 7
100% 131 (longest request)
最佳答案
正如@marcospereira 所说,Play 是一个相对高级的框架,专注于利用 Scala 中更高级的类型系统来为您提供许多功能和安全性,从而帮助您编写可重构的代码并可根据您的需要进行扩展。尽管如此,我在生产中从中获得了出色的性能。
除了建议您尝试使用 native socket transport 在 Linux 上运行基准测试之外,我将重复@marcospereira 所说的,在不停止 Play 服务器的情况下运行基准测试几次。您的 Play 基准测试结果中的标准偏差似乎异常高(平均值为 1,SD 为 2.2),这表明 JIT 可能尚未完全为您完成代码优化。
关于performance - scala Play 2.5 与 golang 基准测试,以及优化 play 框架的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36990707/
一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame
因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实
我目前对后台队列不太满意。我正在尝试让Resque工作。我已经安装了redis和Resquegem。Redis正在运行。一个worker正在运行(rakeresque:workQUEUE=simple)。使用Web界面,我可以看到工作人员正在运行并等待工作。当我运行“rakeget_updates”时,作业已排队但失败了。我已经用defself.perform和defperform试过了。发条.raketask:get_updates=>:environmentdoResque.enqueue(GetUpdates)end类文件(app/workers/get_updates.rb)c
我想用一个(自己的)omniauth提供商来衡量每秒可以登录多少次。我需要了解此omniauth/oauth请求的性能如何,以及此身份验证是否具有可扩展性?到目前为止我得到了什么:defperformance_auth(user_count=10)bm=Benchmark.realtimedouser_count.timesdo|n|forkdoclick_on'Logout'omniauth_config_mock(:provider=>"foo",:uid=>n,:email=>"foo#{n}@example.net")visit"/account/auth/foo/"enden
Rails中有类似RubyBenchmark的东西吗?我过去曾使用Ruby基准测试来比较不同的代码位,但没有一个与Rails相关。我想在一些基准测试中使用我的应用程序模型来做一些类似......#!/usr/bin/rubyrequire'benchmark'Benchmark.bmbmdo|x|x.report("Benchmark1")do1_000_000.timesdo#dosomethinghere...endendx.report("Benchmark2")do1_000_000.timesdo#Dosomethingelsehere...endendend这给了我这样的输
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:'ab'programfreezesafterlotsofrequests,why?这是一个简单的测试服务器:require'rubygems'require'rack'require'thin'classHelloWorlddefcall(env)[200,{"Content-Type"=>"text/plain"},"OK"]endendRack::Handler::Thin.runHelloWorld.new,:Port=>9294#I'vetriedwiththeseaddedtoo,'rack.mu
在我们的Rails3.2.13应用程序(Ruby2.0.0+Heroku上的Postgres)中,我们经常从API中检索大量订单数据,然后我们需要在我们的数据库中更新或创建每个订单,因为以及协会。单个订单创建/更新自身加上大约。10-15个关联对象,我们一次最多导入500个订单。下面的代码可以工作,但问题是它在速度方面一点也不高效。创建/更新500条记录大约需要。1分钟并生成6500多个数据库查询!defadd_details(shop,shopify_orders)shopify_orders.eachdo|shopify_order|order=Order.where(:order
在我的Rails3.2.6应用程序中,我有一个模型表示有关小部件的数据集合。在我看来,此类的正确名称是WidgetData,复数形式,因为每个小部件有不止一项数据。如果我要求Rails为这个类生成一个表单:=form_for@widget_datado|f|...我得到一个错误ActionView::Template::Error(undefinedmethod'widget_datum_path'...。大概这是因为Rails数据/数据变形规则。我不确定如何最好地解决这个问题:我可以让Rails指示我的模型实际上应该是WidgetDatum。或者我可以以某种方式在这种特殊情况下禁用变
我刚刚针对等效的getter/setter方法测试了attr_accessor:classA#wedefinetwoR/Wattributeswithaccessorsattr_accessor:acc,:bcc#wedefinetwoattributeswithgetter/setter-functionsdefdirA=(d);@dirA=d;enddefdirA;@dirA;enddefdirB=(d);@dirB=d;enddefdirB;@dirB;endendvarA=A.newstartT=0dirT=0accT=0#nowwedo100timesthesamebench
基准测试获取一个block并返回时间:http://ruby-doc.org/stdlib-1.9.3/libdoc/benchmark/rdoc/Benchmark.htmlrequire'benchmark'putsBenchmark.measure{"a"*1_000_000}如果你想对一个操作进行基准测试并同时获得返回值和运行时间怎么办?或者,换句话说,闭包可以修改传递给它的对象吗? 最佳答案 闭包可以修改其范围内的对象,如下所示:require'benchmark'a=nilputsBenchmark.measure{a=