Golang在收集上循环时变慢
我从Redis向我的应用程序输入一个json,然后解组并循环 以下是Redis提供的json Im的样子:Golang在收集上循环时变慢,go,Go,我从Redis向我的应用程序输入一个json,然后解组并循环 以下是Redis提供的json Im的样子: [ { "titel": "test 1", "event": "some value", "pair": "some value", "condition": [ "or", [ "contains", "
[
{
"titel": "test 1",
"event": "some value",
"pair": "some value",
"condition": [
"or",
[
"contains",
"url",
"/"
],[
"notcontains",
"url",
"hello"
]
],
"actions": [
[
"option1",
"12",
"1"
],
[
"option2",
"3",
"1"
]
]
}, {
"titel": "test 2",
"event": "some value",
"pair": "some value",
"condition": [
"or",
[
"contains",
"url",
"/"
]
],
"actions": [
[
"option1",
"12",
"1"
],
[
"option2",
"3",
"1"
]
]
}
]
存储json的结构如下所示:
type Trigger struct {
Event string `json:"event"`
Pair string `json:"pair"`
Actions [][]string `json:"actions"`
Condition Condition `json:"condition"`
}
type Condition []interface{}
func (c *Condition) Typ() string {
return (*c)[0].(string)
}
func (c *Condition) Val() []string {
xs := (*c)[1].([]interface{})
ys := make([]string, len(xs))
for i, x := range xs {
ys[i] = x.(string)
}
return ys
}
func (c *Condition) String() (string, string, string) {
return c.Val()[0], c.Val()[1], c.Val()[2]
}
type Triggers struct {
Collection []Trigger
}
for i := range triggers.Collection {
if triggers.Collection[i].Event == "some value" {
fmt.Println("We got: some value")
}
我将其解压到结构中,如下所示:
var triggers Triggers
err := json.Unmarshal([]byte(triggersJson), &triggers.Collection)
if err != nil {
fmt.Println("Error while unmarshaling triggers json: ", err)
}
在用攻城来测试它时,它工作正常,性能完美。
然而,只要我想在结构上开始循环,我就会看到很长的响应时间和超时
这就是我在上面循环的方式:
for _,element := range triggers.Collection {
if element.Event == "some value" {
fmt.Println("We got: some value")
}
}
在500个并发连接上,没有循环的性能为2ms。
循环在500毫秒时达到600毫秒,同时出现一系列超时
理想情况下,我希望更改json的结构,使其不包括:
"or",
但是我不能控制json,所以很遗憾这是不可能的
有什么想法导致这种情况,以及如何解决
编辑
我发现是什么让整个事情变慢了
编辑我的结构,如:
type Trigger struct {
Event string `json:"event"`
Pair string `json:"pair"`
Actions [][]string `json:"actions"`
//Condition Condition `json:"condition"`
}
从600毫秒到100毫秒。但是现在我无法解析条件
现在确定如何用另一种方式解析条件,而不是我目前正在做的,因为它有两种不同的格式,听起来很奇怪,但要尽量避免复制集合元素。大概是这样的:
type Trigger struct {
Event string `json:"event"`
Pair string `json:"pair"`
Actions [][]string `json:"actions"`
Condition Condition `json:"condition"`
}
type Condition []interface{}
func (c *Condition) Typ() string {
return (*c)[0].(string)
}
func (c *Condition) Val() []string {
xs := (*c)[1].([]interface{})
ys := make([]string, len(xs))
for i, x := range xs {
ys[i] = x.(string)
}
return ys
}
func (c *Condition) String() (string, string, string) {
return c.Val()[0], c.Val()[1], c.Val()[2]
}
type Triggers struct {
Collection []Trigger
}
for i := range triggers.Collection {
if triggers.Collection[i].Event == "some value" {
fmt.Println("We got: some value")
}
通常,collectionA循环中有4-50个字符串,比较4-50个字符串不会将执行时间从2ms增加到600ms。正在进行其他操作。请分析您的代码并查看阻塞的内容。您在此处显示的内容不足,无法指示问题。您是否正在打印某些内容?这肯定会让事情慢下来,因为每次调用它的String方法时,你都要对
条件进行3次完整的解析。将这些值复制到另一个正确类型的字段中一次,或者更好的做法是在unmarshal期间执行此操作,以完全删除这些额外的方法。