Как стать автором
Обновить

Комментарии 10

Как-то однобоко:

  • Тест производится на небольшой структуре. Очевидно, что после определенного размера структуры ситуация изменится. После какого?

  • Производительность - это не только скорость, но и потрабление памяти/аллокации

Вот и выросло очередное поколение, заново открывающее для себя числа, которые обязан знать каждый.

Да, понятно, что бывают пограничные случаи, когда сходу неясно что выгоднее — передача по значению или по ссылке. Но если вы будете помнить, что один проход по ссылке, которой не посчастливилось попасть ни в один из кешей эквивалентен пересылке 400-500 байт данных, то вы поймёте, что ссылки имеют смысл сильно реже, чам многим кажется.

Очень смелое утверждение. Чтобы скопировать структуру её нужно прочитать, что приведет к её обновлению в кэше и той же потере времени, что и при обращении по ссылке. Но потом её ещё записать записать, что выпивает из кэша какие другие данные. И где профит?

Вы, вероятно, хотели ответить @khim

В данном случае проблема не в этих числах, а в том, что в куче по-одному создается миллион объектов, которые никак не используются и тут-же уничтожаются, что нагружает GC.

В реальном коде объект создается и какое-то время живет и используется, в этом случае если нам надо работать с оным объектом из разных методов - выгоднее передавать его по ссылке. Однако если это кратковременный объект, чистое ДТО исключительно для передачи каких-то данных из одной функции в другую, то тут может быть действительно выгоднее эти данные передавать через стек, а не через кучу управляемую GC - здесь и выгода, что объект создается и уничтожается сам, без затрат на GC, и дает больше простора всяким оптимизациям во время сборки.

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

В моих задачах еще бы пришлось решать вопрос обратного копирования. Даже подумать страшно, как это решать, интересно что бы сказал автор

В первом тесте бенчится не передача структуры (в функцию) по значению или указателю, а возврат структуры из функции или указателя на неё. Разумеется, в первом случае (возврат структуры) можно (иногда) обойтись без аллокации (положить структуру в стек), а во втором (возврат указателя) без аллокации уже не обойтись.

В то время как передавать структуру в функцию (последний тест, уже без страшных графиков) быстрее всего по указателю, что вполне очевидно.

func BenchmarkMemoryHeap2(b *testing.B) {

    f, err := os.Create("heap.out")
    if err != nil {
        panic(err)
    }
    defer f.Close()

    err = trace.Start(f)
    if err != nil {
        panic(err)
    }

    for i := 0; i < b.N; i++ {
        s := byPointer()
        if s.a != 1 {
            panic("a!=1")
        }
    }

    trace.Stop()
    b.StopTimer()

}

BenchmarkMemoryStack-4 193849980 6.160 ns/op
BenchmarkMemoryHeap-4 18460486 62.46 ns/op
BenchmarkMemoryHeap2-4 195428566 6.141 ns/op


Собственно, уже было

Говоря про типы по значению и по указателю в golang, я бы обязательно говорил, что эти понятия размыты донельзя, поскольку на типе по значению можно вызывать методы по указателю https://play.golang.org/p/IW2bLAfz1l8

Эта "фича" и ещё больше ослабила систему типов, к сожалению.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий