basyura's blog

あしたになったらほんきだす。

正規表現判定

ログをゴニョゴニョして変換したいことがあって C# で書いてたのだけど激しく遅いので golang で書き直した。 golang は正規表現が遅いと書いてあるのだけど諸事情により exe で渡して済ませたいのでひとまずこれで。 でも書き方によって早くならないかなと思って試してみる。

go version go1.10.1 darwin/amd64

package main

import (
    "fmt"
    "regexp"
    "time"
)

func main() {
    line := "[100][200][300][400][500][600][700][800][900]"
    // 194.370089ms
    //regex := regexp.MustCompile(`\[(.*?)\]\[(.*?)\]\[(.*?)\]\[(.*?)\]\[(.*?)\]\[(.*?)\]\[(.*?)\]\[(.*?)\]\[(.*?)\]`)
    // 172.41378ms
    //regex := regexp.MustCompile(`\[(\d*?)\]\[.*?\]\[(\d*?)\]\[.*?\]\[(\d*?)\]\[.*?\]\[(\d*?)\]\[.*?\]\[(\d*?)\]`)
    // 167.32932ms
    //regex := regexp.MustCompile(`\[(.*?)\]\[.*?\]\[(.*?)\]\[.*?\]\[(.*?)\]\[.*?\]\[(.*?)\]\[.*?\]\[(.*?)\]`)

    start := time.Now()
    i := 0
    for {

        regex.FindStringSubmatch(line)
        i++
        if i >= 100000 {
            break
        }
    }

    fmt.Println(time.Since(start))
}

ruby 2.0.0 で試してみる。

line = "[100][200][300][400][500][600][700][800][900]"
# 94.829ms
regex = /\[(.*?)\]\[(.*?)\]\[(.*?)\]\[(.*?)\]\[(.*?)\]\[(.*?)\]\[(.*?)\]\[(.*?)\]\[(.*?)\]/
# 85.917ms
#regex = /\[(\d*?)\]\[.*?\]\[(\d*?)\]\[.*?\]\[(\d*?)\]\[.*?\]\[(\d*?)\]\[.*?\]\[(\d*?)\]/
# 96.525
#regex = /\[(.*?)\]\[.*?\]\[(.*?)\]\[.*?\]\[(.*?)\]\[.*?\]\[(.*?)\]\[.*?\]\[(.*?)\]/

start = Time.now

for i in 0..100000

  if line =~ regex
  end

end

puts (Time.now - start) * 1000