⼤勢でピンポンできるの
は、だれ?
.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)
ピンポンです
ping
pong
多重ピンポンです
ping
pong
ping
pong
ping
pong
ping
pong
ping
pong
HTTP GET /→
pong←
私が「ポン」と返すので、
皆さんは「ピン」と⾔ってください。
私が「ポン」と返すので、
皆さんは「ピン」と⾔ってください。
ピン!
Ping!
私(⼈間っぽい)
竝列數: 30clients
Response time: 250ms以上
Troughput: 約4囘/秒
Error rate: 可成り⾼め
現役のRubyっぽい⾔語達
CoffeeScript(Node.js)
Crystal(Crystal)
Elixir(cowboy)
Groovy(Vert.x)
JRuby(Vert.x)
Opal(Node.js)
Ruby(puma)
Ruby(Unicorn)
現役のRubyっぽい⾔語達
⼤勢でピンポンできるのは、だれ?
CoffeeScript(Node.js)
http = require 'httpʼ
server = http.createServer (req, res) ->
req.on 'data', (_chunk) ->
req.on 'end', ->
res.writeHead 200,
'content-type': 'text/plain',
'content-length': 4
res.end 'pongʼ
server.on 'clientError', (err, socket) ->
console.error err
socket.end 'HTTP/1.1 400 Bad Requestrnrnʼ
server.listen 3000
https://github.com/ne-sachirou/exconfjp2017/tree/megurorb20170420
Crystal(Crystal)
require "http/server”
module PingPong
class App
def initialize(_argv)
server = HTTP::Server.new(3000) do |context|
context.response.content_type = "text/plain”
context.response.print "pong”
end
server.listen
end
end
end
PingPong::App.new ARGV
https://github.com/ne-sachirou/exconfjp2017/tree/megurorb20170420
Elixir(cowboy) 1/3
defmodule PingPong.Application do
@moduledoc false
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [
worker(PingPong.Server, []),
]
opts = [strategy: :one_for_one, name: PingPong.Supervisor]
Supervisor.start_link(children, opts)
end
end
https://github.com/ne-sachirou/exconfjp2017/tree/megurorb20170420
Elixir(cowboy) 2/3
defmodule PingPong.Server do
@moduledoc false
def start_link do
dispatch = :cowboy_router.compile([
{
:_,
[{"/", PingPong.Handler, []}]
}
])
{:ok, _} = :cowboy.start_http :ping_pong,
1000,
[port: 3000, max_connections: 2048],
[env: [dispatch: dispatch]]
end
end
https://github.com/ne-sachirou/exconfjp2017/tree/megurorb20170420
Elixir(cowboy) 3/3
defmodule PingPong.Handler do
@moduledoc false
def init({:tcp, :http}, req, opts), do: {:ok, req, opts}
def handle(req, state) do
{:ok, req} = :cowboy_req.reply 200, [{"content-type", "text/plain"}], "pong", req
{:ok, req, state}
end
def terminate(_reason, _req, _state), do: :ok
end
https://github.com/ne-sachirou/exconfjp2017/tree/megurorb20170420
Groovy(Vert.x)
vertx.createHttpServer().requestHandler({ req ->
req.response()
.putHeader("content-type", "text/plain")
.end("pong")
}).listen(3000)
https://github.com/ne-sachirou/exconfjp2017/tree/megurorb20170420
JRuby(Vert.x)
$vertx.create_http_server.request_handler do |req|
req.response
.put_header('content-type', 'text/plain')
.end('pong')
end.listen(3000)
https://github.com/ne-sachirou/exconfjp2017/tree/megurorb20170420
Opal(Node.js)
`var http = require('http')`
server = `http`.JS.createServer do |req, res|
req_on = req.JS[:on].JS.bind req
req_on.call('data', -> {})
req_on.call('end', lambda do
res.JS.writeHead(
200,
'content-type' => 'text/plain',
'content-length' => 4
)
res.JS.end 'pongʼ
end)
end
server.JS.listen 3_000
https://github.com/ne-sachirou/exconfjp2017/tree/megurorb20170420
Ruby(puma)&Ruby(Unicorn)
# frozen_string_literal: true
# ping-pong
class App
def call(_env)
[200, { 'content-type' => 'text/plain' }, ['pong']]
end
end
run App.new
https://github.com/ne-sachirou/exconfjp2017/tree/megurorb20170420
`make pressure`
https://github.com/ne-sachirou/exconfjp2017/tree/megurorb20170420
timelimit concurrency read write error time throughput error rate
coffeescript_nod
ejs 15 5 62110 62110 0 0.007 828.133 0
coffeescript_nod
ejs 15 50 220134 220134 0 2.337 293.512 0
coffeescript_nod
ejs 15 500 78590 79590 1000 30.978 10.479 1.256
crystal_crystal 15 5 59221 59221 0 0 789.613 0
crystal_crystal 15 50 627692 627692 0 0.055 836.923 0
crystal_crystal 15 500 627030 627030 0 7.893 83.604 0
elixir_cowboy 15 5 60595 60595 0 0.022 807.933 0
elixir_cowboy 15 50 202176 202176 0 2.508 269.568 0
elixir_cowboy 15 500 211333 211333 0 26.145 28.178 0
groovy_vertx 15 5 59896 59896 0 0.013 798.613 0
groovy_vertx 15 50 598866 598866 0 0.146 798.488 0
groovy_vertx 15 500 571604 571604 0 9.256 76.214 0
jruby_vertx 15 5 59294 59294 0 0.05 790.587 0
jruby_vertx 15 50 384061 384061 0 0.884 512.081 0
jruby_vertx 15 500 339131 339131 0 19.829 45.217 0
opal_nodejs 15 5 62825 62825 0 0.013 837.667 0
opal_nodejs 15 50 167892 167892 0 3.41 223.856 0
opal_nodejs 15 500 159234 159234 0 44.864 21.231 0
ruby_puma 15 5 60117 60117 0 0.028 801.56 0
ruby_puma 15 50 267000 267000 0 1.394 356 0
ruby_puma 15 500 212091 212091 0 21.388 28.279 0
ruby_unicorn 15 5 1066 1071 5 25.852 14.213 0.467
ruby_unicorn 15 50 1678 1746 68 137 2.237 3.895
0
100
200
300
400
500
600
700
800
900
1000
coffeescript_nodejs crystal_crystal elixir_cowboy groovy_vertx jruby_vertx opal_nodejs ruby_puma ruby_unicorn
time(5,50,500)
time(5) time(50) time(500)
0
0.01
0.02
0.03
0.04
0.05
0.06
coffeescript_nodejs crystal_crystal elixir_cowboy groovy_vertx jruby_vertx opal_nodejs ruby_puma
time(5)
0
0.5
1
1.5
2
2.5
3
3.5
4
coffeescript_nodejs crystal_crystal elixir_cowboy groovy_vertx jruby_vertx opal_nodejs ruby_puma
time(5,50)
time(5) time(50)
0
5
10
15
20
25
30
35
40
45
50
coffeescript_nodejs crystal_crystal elixir_cowboy groovy_vertx jruby_vertx opal_nodejs ruby_puma
time(5,50,500)
time(5) time(50) time(500)
纏め
Node.jsとUnicornはerror rate⾼くて⾟さう。

大勢でピンポンできるのは、だれ?