Can I optimize this further so that it works faster?

As you can see in the next pprof release, I have these nested for loops that take up most of my program time. The source is in golang, but the code is explained below:

  8.55mins    1.18hrs     20:   for k := range mapSource {
  4.41mins    1.20hrs     21:           if positions, found := mapTarget[k]; found {
         .          .     22:                   // save all matches
  1.05mins   1.05mins     23:                   for _, targetPos := range positions {
  2.25mins   2.33mins     24:                           for _, sourcePos := range mapSource[k] {
     1.28s     15.78s     25:                                   matches = append(matches, match{int32(targetPos), int32(sourcePos)})
         .          .     26:                           }
         .          .     27:                   }
         .          .     28:           }
         .          .     29:   }

I am currently using 2 map[int32][]int32, targetMap and sourceMap.

These cards contain an array from int for the given key. Now I want to find the keys that match on both cards and store the combinations of elements in arrays.

So for example:

sourceMap[1] = [3,4]
sourceMap[5] = [9,10]

targetMap[1] = [1,2,3]
targetMap[2] = [2,3]
targetMap[3] = [1,2]

The only thing in common is 1, and the result will be[(3,1), (3,2), (3,3), (4,1), (4,2), (4,3)]

Is there any possible way (a more suitable data structure or something else) that can improve the speed of my program?

1000 150000 , .

EDIT: Concurrency , .

+6
4

, ?

- ( , ?

.


XY . , , .


, , . ?

, :

BenchmarkPeterSO-4   30    44089894 ns/op    5776666 B/op      31 allocs/op
BenchmarkIvan-4      10   152300554 ns/op   26023924 B/op    6022 allocs/op

, .

+5

, , , :

https://play.golang.org/p/JHAmPRh7jr

package main

import (
    "fmt"
    "sync"
)

var final [][]int32
var wg sync.WaitGroup
var receiver chan []int32
func main() {
    final = [][]int32{}
    mapTarget := make(map[int32][]int32)
    mapSource := make(map[int32][]int32)
    mapSource[1] = []int32{3, 4}
    mapSource[5] = []int32{9, 10}

    mapTarget[1] = []int32{1, 2, 3}
    mapTarget[2] = []int32{2, 3}
    mapTarget[3] = []int32{1, 2}
    wg = sync.WaitGroup{}
    receiver = make(chan []int32)
    go func() {
        for elem := range receiver {
            final = append(final, elem)
            wg.Done()
        }
    }()
    for k := range mapSource {
        if _, ok := mapTarget[k]; ok {
            wg.Add(1)
            go permutate(mapSource[k], mapTarget[k])
        }
    }
    wg.Wait()
    fmt.Println(final)

}

func permutate(a, b []int32) {
    for i := 0; i < len(a); i++ {
        for j := 0; j < len(b); j++ {
            wg.Add(1)
            receiver <- []int32{a[i], b[j]}
        }
    }
    wg.Done()
}

, , :

for k := range mapSource {
      wg.Add(1)
      go func(k int32) {
          if _, ok := mapTarget[k]; ok {
              wg.Add(1)
              go permutate(mapSource[k], mapTarget[k])
          }
          wg.Done()
      }(k)
 }
+1

, , , , , , , , , .

, , 2x ( ), .

var sources, targets []int32

for k, srcPositions := range mapSource {
    if tgtPositions, found := mapTarget[k]; found {
        sources = append(sources, srcPositions...)
        targets = append(targets, tgtPositions...)
    }
}

matches = make([]match, len(sources) * len(targets))
i := 0
for _, s := range(sources) {
    for _, t := range(targets) {
        matches[i] = match{s, t}
        i++
    }
}

, , , . , , . , , , , .

0
:
  • .

  • , 1.

  • .

, , node.

type node struct {
    val    int
    parent *node
    next   *node
    child  *node
}

type tree struct {
    root  *node
    level int
}

var sourceMap map[int]*tree
-1

All Articles