начальный цикл голанга медленнее, чем остаток - PullRequest
0 голосов
/ 23 мая 2019

Я новичок в golang. Во время выполнения этого документа я заметил странное поведение при выполнении цикла for.

    package main;

    import (
        "log"
        "strings"
        "time"
    )

    type data struct {
        elapseTime int64
        data string
    }



    func main(){
        for i := 0 ; i < 10; i++{

            c := make(chan data);
            go removeDuplicates("I love oranges LALALA I LOVE APPLES LALALA XD", c);
            log.Printf("%v", <- c);
        }
    }





    func removeDuplicates(value string , c chan data){
        start := time.Now();
        var d = data{};
        var r string;
        value = strings.ToLower(value);
        var m = make(map[string]string);
        splitVals := strings.Split(value, " ");
        for _, element := range splitVals {
            if _, ok := m[element]; ok == false {
                m[element] = element;
            }
        }
        for k, _ := range m {
            r = r + k + " ";
        }
        d.data = strings.TrimRight(r, "");
        d.elapseTime = time.Since(start).Nanoseconds();
        c <- d;
    }

По сути, я пытаюсь добиться того, чтобы удалить дубликаты простой строки и распечатать эту информацию вместе с затраченным временем.цикл проходит через подпрограмму go 10 раз, ожидая получения ответов по каналу.

2019/05/24 00:55:49 {18060 i love oranges lalala apples xd }
2019/05/24 00:55:49 {28930 love oranges lalala apples xd i }
2019/05/24 00:55:49 {10393 i love oranges lalala apples xd }
2019/05/24 00:55:49 {1609 oranges lalala apples xd i love }
2019/05/24 00:55:49 {1877 i love oranges lalala apples xd }
2019/05/24 00:55:49 {1352 i love oranges lalala apples xd }
2019/05/24 00:55:49 {1708 i love oranges lalala apples xd }
2019/05/24 00:55:49 {1268 apples xd i love oranges lalala }
2019/05/24 00:55:49 {1736 oranges lalala apples xd i love }
2019/05/24 00:55:49 {1037 i love oranges lalala apples xd }

Вот что я вижу: первые несколько отпечатков цикла (не имеет значения, является ли один цикл или100x loop) будет значительно медленнее, чем остальные циклы.Есть ли причина, почему это так?(время выполнения в наносекундах между прочим)

Редактировать: удаление части переключателя, так как люди запутались в вопросе.

1 Ответ

2 голосов
/ 23 мая 2019

Параллельность - это не параллелизм. Это конкретное использование канала оказывается очень похожим на простое возвращение значений из removeDuplicates, за исключением того, что есть две служебные нагрузки от двух программ, нуждающихся в координации их использованияchannel.

В частности:

  • Каждая итерация цикла имеет свой собственный канал, и каждый канал может содержать только один элемент.
  • Цикл не может продолжаться доследующая итерация, пока не будут выполнены все операторы, включая вызов log.Printf, который блокирует, пока значение не будет получено из канала.
  • removeDuplicates определяет, сколько прошло в реальном времени, а не сколько было потрачено времениработает над своей проблемой.Это одна из многих причин, по которым в комментариях говорится, что это не очень хороший тест в первую очередь.

Спекулятивный: Возможно, что в первые несколько итераций циклаremoveDuplicates программа выполняет инициализацию start, а затем возвращает время выполнения основной программе.Затем основная программа немедленно проверяет мьютекс на c, обнаруживает, что он еще ничего не может сделать, и возвращает к планировщику, и вся эта проверка и переключение контекста добавляет тысячи наносекунд (забота об этом обычно является запахом микробенчмаркинг ) для выполнения в реальном времени removeDuplicates goroutine.После нескольких итераций кое-что (возможно, среда выполнения Go) обнаруживает тот факт, что main никогда не сможет добиться прогресса, пока не вернется removeDuplicates, и переключение контекста будет исключено.

Я знаю, что на данный момент вы больше заинтересованы в объяснениях, чем в советах, , но я чувствовал бы себя довольно безответственно, если бы не указал, что тесты сравнения Go to Java уже существуют .Даже если вы хотите написать свой собственный, я бы порекомендовал использовать аналогичный подход: определить эталонную программу с точки зрения того, что она должна выполнить, а затем использовать лучшие инструменты, доступные на каждом языке (или фреймворке), чтобы выполнить работус хорошей производительностью.

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