当我为我的算法编写基准测试时,我被一个问题弄糊涂了!
我的测试代码详细信息已推送到 github,我将其复制到此处并添加了一些注释。
https://github.com/hidstarshine/Algorithm/blob/master/leet/problem24_test.go
var TDBenchmarkSwapPairs1 *leet.ListNode
// This function may be not good, it should be init()?
func FTDBenchmarkSwapPairs1() {
TDBenchmarkSwapPairs1 = &leet.ListNode{
Val: 0,
Next: nil,
}
changeNode := TDBenchmarkSwapPairs1
for i := 1; i < 100; i++ {
changeNode.Next = &leet.ListNode{
Val: i,
Next: nil,
}
changeNode = changeNode.Next
}
}
func BenchmarkSwapPairs1(b *testing.B) {
FTDBenchmarkSwapPairs1() // problem is here
for i := 0; i < b.N; i++ {
leet.SwapPairs1(TDBenchmarkSwapPairs1)
}
}
在问题行中,我调用 FTDBenchmarkSwapPairs1(FTD 表示填充测试数据)来初始化数据。
然后发生了一些令人惊奇的事情,BenchmarkSwapPairs1 似乎在许多 goroutine 中运行。
因此并发带来了数据竞争,并且由于 SwapPairs1 特殊的逻辑,调试变得一团糟。
SwapPairs1 将更改 ListNode 中的 Next。
然后我想将 BenchmarkSwapPairs1 移动到 for 块来解决这个问题。
但是数据竞赛似乎仍未解决,并且由于初始化时间的原因,基准测试没有任何意义。
我在 leetcode 上判断算法并被接受!
问:我怎样才能优雅地解决这个问题?需要一个好主意!
新的@Jimb
我添加只是添加一些调试信息然后它恐慌。我也认为它一开始不会有数据竞赛。
当我看到恐慌时,我做出了假设!
package leet_test
import (
"fmt"
"testing"
"github.com/hidstarshine/Algorithm/leet"
)
var TDBenchmarkSwapPairs1 *leet.ListNode
func FTDBenchmarkSwapPairs1() {
TDBenchmarkSwapPairs1 = &leet.ListNode{
Val: 0,
Next: nil,
}
changeNode := TDBenchmarkSwapPairs1
for i := 1; i < 100; i++ {
changeNode.Next = &leet.ListNode{
Val: i,
Next: nil,
}
changeNode = changeNode.Next
}
AnotherChangeNode := TDBenchmarkSwapPairs1
for AnotherChangeNode != nil {
fmt.Println(AnotherChangeNode)
AnotherChangeNode = AnotherChangeNode.Next
}
}
func BenchmarkSwapPairs1(b *testing.B) {
FTDBenchmarkSwapPairs1()
for i := 0; i < b.N; i++ {
fmt.Println(TDBenchmarkSwapPairs1.Next)
fmt.Println(TDBenchmarkSwapPairs1.Next.Next)
fmt.Println(TDBenchmarkSwapPairs1.Next.Next.Next)
fmt.Println(TDBenchmarkSwapPairs1.Next.Next.Next.Next)
leet.SwapPairs1(TDBenchmarkSwapPairs1)
}
}
恐慌信息(重要)
more...
&{98 0xc000044ac0}
&{99 <nil>}
&{1 0xc000044270}
&{2 0xc0000444a0}
&{3 0xc0000444c0}
&{4 0xc0000444d0}
Some system info
&{15 0xc000044ae0}
&{2 0xc000044bd0}
&{17 0xc000044b00}
&{4 0xc000044bf0}
&{17 0xc000044ae0}
Unorderd message
<nil>
&{4 0xc000044ae0}
&{2 <nil>}
<nil>
panic: runtime error: invalid memory address or nil pointer dereference // why
[signal 0xc0000005 code=0x0 addr=0x8 pc=0xbefb20]