正则表达式的运行时优化

huangapple go评论71阅读模式
英文:

Runtime optimization for regular expression

问题

大多数正则表达式在其生命周期中都是“常量”。使用全局正则表达式来加快执行速度是一个好主意吗?例如:

func work() {
    r := regexp.MustCompile(`...`)
    if r.MatchString(...) {
        ...
    }
}

与以下代码进行比较:

var r *regexp.Regexp

func work() {
    if r.MatchString(...) {
        ...
    }
}

func init() {
    r = regexp.MustCompile(`...`)
}

这两个版本有什么有意义的区别吗?

  1. 正则表达式的编译非常廉价,因此在CPU成本和垃圾回收方面都不值得使用全局正则表达式(假设work()被频繁调用)。
  2. 在适当的情况下,最好使用全局正则表达式。

以上哪个是正确的,或者答案并不是简单的黑白之分?

英文:

Most regular expression is "constant" in their life time. Is it a good idea to use global regular expression to speed up execution? For example:

func work() {
    r := regexp.MustCompile(`...`)
    if r.MatchString(...) {
        ...
    }
}

comparing with:

var r *regexp.Regexp

func work() {
    if r.MatchString(...) {
        ...
    }
}

func init() {
    r = regexp.MustCompile(`...`)
}

Do these 2 versions has any meaningful difference?

  1. Regular expression compiling is so cheap so that it is not worth to use global regex, both in term of CPU cost and garbage collecting (suppose work() is heavily called)
  2. It is better to use global regular expression whenever approriate.

Which of the above is correct, or the answer is not simply black/white?

答案1

得分: 2

如果你只使用相同的正则表达式(例如"\d+")一次,那么使用全局正则表达式是不值得的。

如果你经常使用相同的正则表达式(例如"\d+"),那么使用全局正则表达式是值得的。

func Benchmark01(b *testing.B) {
	for i := 0; i < b.N; i++ {
		r := regexp.MustCompile(`\d+`)
		r.MatchString("aaaaaaa123bbbbbbb")
	}
}

func Benchmark02(b *testing.B) {
	r := regexp.MustCompile(`\d+`)
	for i := 0; i < b.N; i++ {
		r.MatchString("aaaaaaa123bbbbbbb")
	}
}
Benchmark01
Benchmark01-4             886909              1361 ns/op
Benchmark02
Benchmark02-4            5368380               232.8 ns/op
英文:

if you use same regular expression(eg "\d+") just once -> it is not worth to use global regex.

if you use same regular expression(eg "\d+") often -> it is worth to use

func Benchmark01(b *testing.B) {
	for i := 0; i &lt; b.N; i++ {
		r := regexp.MustCompile(`\d+`)
		r.MatchString(&quot;aaaaaaa123bbbbbbb&quot;)
	}
}

func Benchmark02(b *testing.B) {
	r := regexp.MustCompile(`\d+`)
	for i := 0; i &lt; b.N; i++ {
		r.MatchString(&quot;aaaaaaa123bbbbbbb&quot;)
	}
}

Benchmark01
Benchmark01-4             886909              1361 ns/op
Benchmark02
Benchmark02-4            5368380               232.8 ns/op

huangapple
  • 本文由 发表于 2023年2月6日 14:12:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75357891.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定