Я занимаюсь программированием, в котором задача состоит в том, чтобы декодировать каждую строку текстового файла и найти правильное английское слово. Строки кодируются несколько раз с помощью base64, поэтому задача состоит в цикле, пока не будет найдено, что декодированное значение является допустимым английским словом (проверено с помощью встроенного локального dict).
Первоначально разработано это на ThinkPad 460 сi5 работает под управлением Ubuntu, но ему было любопытно, как это будет работать на MacBook последнего поколения с i9, к которому у меня только что получился доступ.
К моему большому удивлению, код работал намного хуже ... Ниже приведены некоторые тесты:
[MacBook]
interpretation 285.76ms
lawn 425.63ms
unifying 1.10s
electives 1.20s
sanctioned 6.18s
[ThinkPad]
interpretation 32.61ms
lawn 59.31ms
electives 91.10ms
unifying 93.60ms
sanctioned 141.28ms
Мне было интересно, может ли кто-нибудь указать на некоторые намеки о том, почему это так? Я даже реализовал правильную параллельную обработку, чтобы максимально ускорить процесс, но MacBook по-прежнему работает намного хуже, чем 4-летний и менее мощный ThinkPad. Интересно, это из-за какой-то архитектурной разницы?
Во время тестирования я не компилировал код ни на одной из платформ, а просто использовал "go run main.go [args ...]", чтобы запустить его локально.
// helper func to look up a given string in dictionary (location depends on OS)
func dictLookup(word string) bool {
var dictLocation string
if runtime.GOOS == "darwin" {
dictLocation = "american-english"
} else {
dictLocation = "/usr/share/dict/american-english"
}
_, err := exec.Command("grep", "-w", word, dictLocation).Output()
if err != nil {
return false
}
return true
}
// helper func to decode a base64 encoded string (append necessary = at end to make it valid...)
func decode(src string) string {
data, err := base64.StdEncoding.DecodeString(src)
if err != nil {
src2 := src + "="
data2, err2 := base64.StdEncoding.DecodeString(src2)
if err2 != nil {
src3 := src2 + "="
data3, _ := base64.StdEncoding.DecodeString(src3)
return string(data3)
}
return string(data2)
}
return string(data)
}
func workerFunc(jobs <-chan string, results chan<- string, wg *sync.WaitGroup) {
// Decreasing internal counter for wait-group as soon as goroutine finishes
defer wg.Done()
// eventually I want to have a []string channel to work on a chunk of lines not just one line of text
for j := range jobs {
start := time.Now()
line := decode(j)
// test and further decode until valid work is found
for !(dictLookup(line)) {
line = decode(line)
}
elapsed := time.Since(start)
results <- fmt.Sprintf("%s \t%s", line, elapsed)
}
}
Заранее спасибо за любую помощь!