我有一个很大的N * 1名字阵列
我目前正在使用goroutine计算名称之间的编辑距离
问题是[B] [C]的结果不同,也许就像
ABC BCD 7
ABC BCD 3
名称中有20000条记录
var names []string
将名称划分为两个块
nameCount := len(names)
procs := 2
chunkSize := nameCount / procs
频道
ch := make(chan int)
var wg sync.WaitGroup
for i := 0; i < procs; i++ { //create two goroutines
start := i * chunkSize
end := (i+1)*chunkSize - 1
fmt.Println(start, end) //get slice start and end
wg.Add(1)
go func(slices []string, allnames []string) {
for _, slice := range slices {
minDistance = 256
distance := 0
sum := 0
for _, name := range allnames {
distance = calcEditDist(slice, name) //get the LD [A]
sum += 1
if distance > 0 && distance < minDistance {
minDistance = distance
fmt.Println(slice, name, distance) //[B]
fmt.Println(slice, name, calcEditDist(slice, name)) //[C]
} else if distance == minDistance {
fmt.Println(slice, name, distance)
fmt.Println(slice, name, calcEditDist(slice, name))
}
}
// for _, name := range allnames {
// fmt.Println(slice, name)
// }
ch <- sum
// fmt.Println(len(allnames), slice)
break
}
wg.Done()
}(names[start:end], names)
}
我放置了calcEditDist @ https://github.com/copywrite/keyboardDistance/blob/master/parallel.go
PS:
如果我宣布
var dp [max][max]int
更新1
感谢所有伙伴,我在下面分三步采取了很好的建议
1)我将dp缩小到一个非常合理的尺寸,如100或甚至更小,DONE
2)我把dp声明放在每个goroutine中并传递它的指针,就像Nick说的那样,DONE
3)稍后我将尝试动态分配dp,LATER
性能急剧提升,╰(°▽°)╯
答案 0 :(得分:1)
正如您在帖子中指出的那样,将dp
作为全局变量是问题所在。
每次在CalcEditDistance
分配它都太慢了。
您有两种可能的解决方案。
1)每个go例程只需要1 dp
个数组,所以在for循环中分配它并传递一个指针(不要直接传递数组,因为数组会传递值,这将涉及到很多复制!)
for i := 0; i < procs; i++ { //create two goroutines
start := i * chunkSize
end := (i+1)*chunkSize - 1
fmt.Println(start, end) //get slice start and end
wg.Add(1)
go func(slices []string, allnames []string) {
var dp [max][max]int // allocate
for _, slice := range slices {
minDistance = 256
distance := 0
sum := 0
for _, name := range allnames {
distance = calcEditDist(slice, name, &dp) // pass dp pointer here
更改calcEditDist以获取dp
func CalcEditDist(A string, B string, dp *[max][max]int) int {
lenA := len(A)
lenB := len(B)
2)重新编写calcEditDistance
,这样就不需要大量的O(N ^ 2)dp数组了。
如果你仔细研究这个函数,它只能访问一行和左边的一列,所以你实际需要的所有存储都是前一行和前一列,你可以用很少的成本动态分配。这也可以使它扩展到任何长度的字符串。
虽然需要一点仔细考虑!