Go проблема с производительностью на MacBook - PullRequest
0 голосов
/ 11 ноября 2019

Я занимаюсь программированием, в котором задача состоит в том, чтобы декодировать каждую строку текстового файла и найти правильное английское слово. Строки кодируются несколько раз с помощью 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)
    }
}

Заранее спасибо за любую помощь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...