2015/11/20


ミドルウェアとして Use するだけでパフォーマンスが向上するなんて夢の様な話はないと思っていたけど、HTTP Coala はそれをやってのけている様です。

goware/httpcoala · GitHub

Go http middleware handler for request coalescing

https://github.com/goware/httpcoala

ちょっと信じがたかったので、まずはベンチマークを取ってみた。

Coala 未使用

package main

import (
    "net/http"

    "github.com/zenazn/goji"
    "github.com/zenazn/goji/web"
)

func main() {
    goji.Get("/"func(c web.C, w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello World"))
    })
    goji.Serve()
}
$ ab -n 10 -n 10000 http://localhost:8000/
Server Software:
Server Hostname:        localhost
Server Port:            8000

Document Path:          /
Document Length:        11 bytes

Concurrency Level:      10
Time taken for tests:   4.185837 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1280000 bytes
HTML transferred:       110000 bytes
Requests per second:    2389.01 [#/sec] (mean)
Time per request:       4.186 [ms] (mean)
Time per request:       0.419 [ms] (mean, across all concurrent requests)
Transfer rate:          298.63 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       7
Processing:     0    3   1.5      4      31
Waiting:        0    2   1.5      2      30
Total:          0    3   1.5      4      31

Percentage of the requests served within a certain time (ms)
  50%      4
  66%      4
  75%      4
  80%      4
  90%      5
  95%      6
  98%      7
  99%      8
 100%     31 (longest request)

Coala 使用

package main

import (
    "net/http"

    "github.com/goware/httpcoala"
    "github.com/zenazn/goji"
    "github.com/zenazn/goji/web"
)

func main() {
    goji.Get("/"func(c web.C, w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello World"))
    })
    goji.Use(httpcoala.Route("GET")) // ココ
    goji.Serve()
}
Server Software:
Server Hostname:        localhost
Server Port:            8000

Document Path:          /
Document Length:        11 bytes

Concurrency Level:      10
Time taken for tests:   3.860772 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1280000 bytes
HTML transferred:       110000 bytes
Requests per second:    2590.16 [#/sec] (mean)
Time per request:       3.861 [ms] (mean)
Time per request:       0.386 [ms] (mean, across all concurrent requests)
Transfer rate:          323.77 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       1
Processing:     0    3   2.2      3      74
Waiting:        0    2   2.3      2      71
Total:          0    3   2.2      3      74

Percentage of the requests served within a certain time (ms)
  50%      3
  66%      3
  75%      4
  80%      4
  90%      4
  95%      5
  98%      5
  99%      6
 100%     74 (longest request)

確かに若干ですがパフォーマンスが良くなってる。README.md によるとスレッド数を上げると

Without httpcoala middleware, Requests/sec:   7081.09
   With httpcoala middleware, Requests/sec:  18373.87

2倍以上の差が出る場合もある様です。何がそうさせるのだろうとコードを読んでみた。

httpcoala/httpcoala.go at master · goware/httpcoala · GitHub
https://github.com/goware/httpcoala/blob/master/httpcoala.go

複数のリクエストを channel を使って結合し、同じレスポンスを返すという仕組みで毎回 ResponseWriter の生成や切断時処理を行うのを回避してる。ハンドラ内が遅くなればなるほど効果が出ます。

httpcoala/httpcoala.go at master · goware/httpcoala · GitHub
https://github.com/goware/httpcoala/blob/master/httpcoala.go#L71-L78

今回の様に同じ URL に対して同じメソッドのリクエストが頻繁に起こる場合には非常に有効な手段だと分かる。キャッシュではない為、リアルタイム性も担保される。なかなかいい所に目を付けてるなーと思った。

効果には個人差がある様です。

The Go Programming Language (Addison-Wesley Professional Computing Series) The Go Programming Language (Addison-Wesley Professional Computing Series)
Alan A. A. Donovan
Addison-Wesley Professional / (2015-11-16)
 
発送可能時間:


2015/11/17


Ruby - マイナンバーのチェックデジットを計算する - Qiita

## そもそもマイナンバーってどういう数字なのでしょうか? これは法律を読みます。調べると「[行政手続における特定の個人を識別するための番号の利用等に関する法律施行令](http://law.e-go...

http://qiita.com/qube81/items/fa6ef94d3c8615b0ce64

もうすぐウチにも届くだろうから何時でも検証出来る準備をしないといけない。という事で書きました。ロジックは KoRoN さんのをパクった。

mattn/vim-mynumber · GitHub

Validate your MyNumber

https://github.com/mattn/vim-mynumber

どうぞ、お役立て下さい。


2015/11/06


RubyからGoの関数をつかう → はやい - Qiita

約20倍はやい!!!!!!すごい!!!!!!!!!!!!!!

Go単体での実行に毛が生えた程度になりました!!!!!!!!!!!!!!!!!!

もう「Rubyより、ずっとはやい」なんて言わせないぞ!!!!!!!!

http://qiita.com/grj_achm/items/679b3f3af2cf377f0f02
def fib(n)
  return n if n <= 1
  fib(n - 1) + fib(n - 2)
end

puts fib(40)

巷で良く見る fib のコードですね。

$ time ruby fib1.rb
102334155
real    12.692
system  0.031
user    12.651

これを再帰を使わない様に修正すると以下の様になります。

def fib(n)
  f0, f1, v = 010
  n.times do |x|
    if x <= 1
      v = x
    else
      v = f0 + f1
      f0, f1 = f1, v
    end
  end
  return f0 + f1
end

puts fib(40)
$ time ruby fib0.rb
102334155
real    0.072
system  0.031
user    0.031

約400倍はやい!!!!!!すごい!!!!!!!!!!!!!!