Wpis z mikrobloga

Przy testowaniu pakietu algorytmu odkryłem rzecz która mnie bardzo zastanawia, mianowicie czas wykonywania pętli. Ktoś mądry odpowie mi dlaczego te czasy wykonania pętli są tak różne?

Kod

Gdy zakomentuje funkcje anonimowaw i puszcze tylko go fuzzy.EditDistance(str1, str2+strconv.Itoa(i)) czas wykonania to ok 330ms

for i := 0; i < 1000000; i++ {
go fuzzy.EditDistance(str1, str2+strconv.Itoa(i)) // 330.1175ms
//go func(str1 string, str2 string, i int) {
// fuzzy.EditDistance(str1, str2+strconv.Itoa(i))
//}(str1, str2, i)
}

Gdy odpalam tylko funckje anonimową czas wykonania wynosi ok 3 sekund

for i := 0; i < 1000000; i++ {
//go fuzzy.EditDistance(str1, str2+strconv.Itoa(i))
go func(str1 string, str2 string, i int) {
fuzzy.EditDistance(str1, str2+strconv.Itoa(i))
}(str1, str2, i) // 3.166537s
}

Natomiast najbardziej ciekawe jest to gdy obie operacje wykonywane są jednocześnie czas wynosi ok 700ms

for i := 0; i < 1000000; i++ {
go fuzzy.EditDistance(str1, str2+strconv.Itoa(i))
go func(str1 string, str2 string, i int) {
fuzzy.EditDistance(str1, str2+strconv.Itoa(i))
}(str1, str2, i)

// Razem 705.114ms
}

#golang #go #programowanie
  • 3
@CandyCancer: Dwie mozliwe rzeczy. Pierwsza z nich to ze twoj kod jest inaczej optymalizowany przez kompilator. Druga - pewnie branch prediction ma na to wplyw (czyli procesor lepiej 'przewiduje' co sie stanie a co nie). Widzialem kiedy przyklad ze usuniecie linijka ktora nic nie robila (to chyba bylo przypisanie do samego siebie wartosci), przyspieszalo sporo dzialanie programu.
@CandyCancer: U mnie jest 318ms, 1s-2s, 541ms (sama pierwsza funkcja, sama druga, obie). Drugi czas potrafi się sporo wahać.

Sprawdziłem wygenerowane kody, wyglądają całkiem podobnie. Jeśli odpalę z GOMAXPROCS=1, to jest 1.60s, 1.85s, 3.20s, więc podobnie. IMHO optymalizacje kompilatora odgrywają małą rolę w tym przypadku ;p

perf stat -e cache-references,cache-misses pokazuje 1.5%, 40%, 2% cache misses, więc pewnie problem leży w tym jak scheduler GO wykonuje te funkcje :)