まず、Standaloneサーバが速いと言われる理由としてsendfile(2)を使っているのですが、Windowsにはsendfile(2)がありません。しかしソケット前提であるならばTransmitFileというAPIがあります。
sendfile(2)と同じようにZeroCopyでファイルから指定ディスクリプタに流し込むAPIです。
Plackが使っているSys::Sendfileに対してこのAPIを使う様にWindowsポーティングしました。
Sys::Sendfileのauthorにもpull requestを送りました。次にPlackにてWindowsで使えないAPIを叩いている部分に対するpatchを書きました。
これで一応、高速化対応は完了。
Plackに付属の画像を返すpsgiアプリケーションを起動してベンチマークを取ってみました。
# plackup -s Standalone -a eg/dot-psgi/image.psgi
ベンチマーク結果は以下の通り。まず高速化対応前。
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
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).....done
Server Software: Plack-Server-Standalone/0.01
Server Hostname: localhost
Server Port: 8080
Document Path: /
Document Length: 2397678 bytes
Concurrency Level: 1
Time taken for tests: 1.219 seconds
Complete requests: 10
Failed requests: 0
Write errors: 0
Total transferred: 23978730 bytes
HTML transferred: 23976780 bytes
Requests per second: 8.21 [#/sec] (mean)
Time per request: 121.876 [ms] (mean)
Time per request: 121.876 [ms] (mean, across all concurrent requests)
Transfer rate: 19213.49 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 2 4.9 0 16
Processing: 109 119 10.9 125 141
Waiting: 0 5 7.5 0 16
Total: 109 120 12.9 125 141
Percentage of the requests served within a certain time (ms)
50% 125
66% 125
75% 125
80% 141
90% 141
95% 141
98% 141
99% 141
100% 141 (longest request)
そして対応後
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
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).....done
Server Software: Plack-Server-Standalone/0.01
Server Hostname: localhost
Server Port: 8080
Document Path: /
Document Length: 2397701 bytes
Concurrency Level: 1
Time taken for tests: 0.578 seconds
Complete requests: 10
Failed requests: 0
Write errors: 0
Total transferred: 23978960 bytes
HTML transferred: 23977010 bytes
Requests per second: 17.30 [#/sec] (mean)
Time per request: 57.813 [ms] (mean)
Time per request: 57.813 [ms] (mean, across all concurrent requests)
Transfer rate: 40504.51 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 3 6.6 0 16
Processing: 31 55 22.4 47 94
Waiting: 0 3 6.6 0 16
Total: 31 58 24.5 47 109
Percentage of the requests served within a certain time (ms)
50% 47
66% 47
75% 63
80% 94
90% 109
95% 109
98% 109
99% 109
100% 109 (longest request)
だいたいRequests perl secondで2倍くらい速くなってます。すばらしい。miyagawa++ kazuho++ Plack++