Я ищу несколько общих советов по оптимизации производительности.
У меня довольно сложный фрагмент кода, но код живет в функции (без глобальных), поэтому я могу либо a) вызвать эта функция в нескольких программах (у меня на машине 12 ядер). Или б) используйте функцию такого же типа, которая вызывается один раз, скомпилируйте мою go программу и выполните все это 4 раза параллельно.
Вот пример кода с таким же поведением:
package main
import (
"fmt"
"runtime"
"time"
)
const size = 140000
type BigStruct struct {
first []int
second []int
}
func slowFunc() int {
// make local variables
sum := 0
myData := BigStruct{}
myData.first = make([]int, 0, size)
// fill some slices
for i := 0; i < size; i++ {
myData.first = append(myData.first, i)
myData.second = append(myData.second, i)
}
// do pointless calculations
for i := range myData.first {
for j := range
myData.second {
if myData.first[i] == myData.second[j] {
sum++
}
}
}
return sum
}
func slowFuncChan(output chan int) {
// make local variables
sum := 0
myData := BigStruct{}
myData.first = make([]int, 0, size)
// fill some slices
for i := 0; i < size; i++ {
myData.first = append(myData.first, i)
myData.second = append(myData.second, i)
}
// do pointless calculations
for i := range myData.first {
for j := range
myData.second {
if myData.first[i] == myData.second[j] {
sum++
}
}
}
output <- sum
}
func main() {
numCPUs := runtime.NumCPU()
runtime.GOMAXPROCS(numCPUs)
fmt.Println("numCPUs: ", numCPUs)
fmt.Println("Calling slowFunc once...")
start := time.Now()
fmt.Println("sum: ", slowFunc())
t := time.Now() // test
elapsed := t.Sub(start)
fmt.Println("time elapsed: ", elapsed)
fmt.Println()
fmt.Println("Calling slowFunc 4x in goroutines...")
output := make(chan int, 4)
for w := 0; w < 4; w++ {
go slowFuncChan(output)
}
for a := 0; a < 4; a++ {
fmt.Println("sum: ", <-output)
}
t2 := time.Now() // test
elapsed = t2.Sub(t)
fmt.Println("time elapsed: ", elapsed)
}
Когда я использую 4 программы, это занимает примерно 2 раза больше, а скомпилированная программа запускается в 4 раза параллельно! И 4 копии программы, работающей параллельно, похоже, работают немного медленнее, чем одна работающая версия, то есть очень хорошо масштабируются.
Это вывод одной программы:
numCPUs: 12
Calling slowFunc once...
sum: 140000
time elapsed: 10.8093226s
Calling slowFunc 4x in goroutines...
sum: 140000
sum: 140000
sum: 140000
sum: 140000
time elapsed: 22.4335858s
Используя командный файл, я запускаю программу 4 раза одновременно и получаю 4 результата:
numCPUs: 12
Calling slowFunc once...
sum: 140000
time elapsed: 12.7615683s
,
numCPUs: 12
Calling slowFunc once...
sum: 140000
time elapsed: 12.7705668s
,
numCPUs: 12
Calling slowFunc once...
sum: 140000
time elapsed: 12.2635664s
,
numCPUs: 12
Calling slowFunc once...
sum: 140000
time elapsed: 12.1155655s
Общее время запуска 4-х одновременных программ составляет 12,7705668 с и почти вдвое меньше, чем у версии с программами (22.4335858s)
Я проверил это с 8 программами по сравнению с 8 одновременными программами, и получили тот же результат с несколькими приложениями, работающими в 2 раза по сравнению с одной версией программы.