2014-06-27 8 views
10

Biorąc pod uwagę następujące struct:Go - Wydajność - jaka jest różnica między wskaźnikiem i wartością w struct?

type Exp struct { 
    foo int, 
    bar *int 
} 

Jaka jest różnica w perspektywie wydajność podczas korzystania wskaźnik lub wartość w struct. Czy jest jakieś obciążenie lub to tylko dwie szkoły programowania Go?

Używałbym wskaźników do implementacji powiązanej struktury, ale czy jest to jedyny przypadek, w którym musimy użyć wskaźników w struct, aby uzyskać wydajność?

PS: w powyższej struktury mówimy o prostym int ale może to być dowolny inny typ (nawet zwyczaj jeden)

Odpowiedz

21

Użyj formularza, który jest najbardziej przydatny dla twojego programu. Zasadniczo oznacza to, że przydatne jest, aby wartość była nil, a następnie użyj wskaźnika.

Z perspektywy wydajności prymitywne typy liczbowe są zawsze bardziej wydajne do kopiowania niż do dereferencji wskaźnika. Jeszcze bardziej złożone struktury danych są zwykle szybsze do skopiowania, jeśli są mniejsze niż linia lub dwa cache (poniżej 128 bajtów jest dobrą zasadą dla procesorów x86).

Gdy rzeczy stają się nieco większe, musisz sprawdzić, czy wydajność Cię dotyczy. Procesory są wydajne przy kopiowaniu danych i istnieje wiele zmiennych, które określają lokalizację i przyjazność pamięci podręcznej twoich danych, to naprawdę zależy od zachowania twojego programu i sprzętu, którego używasz.

To doskonała seria artykułów, jeśli chcesz lepiej zrozumieć interakcję pamięci i oprogramowania: "What every programmer should know about memory".

Mówiąc krótko, mówię ludziom, aby wybierali wskaźnik, czy nie, w oparciu o logikę programu, i martwili się później o wydajność.

  • Użyj wskaźnika, jeśli chcesz przekazać coś do zmodyfikowania.
  • Użyj wskaźnika, jeśli chcesz określić, czy coś było nieuzbrojone/zero.
  • Użyj wskaźnika, jeśli używasz typu, który ma metody z odbiornikami wskazówek.
+1

Dodałem tylko jedno wyjaśnienie do twojej znakomitej odpowiedzi: brak czwartego punktu wypunktowania: "w przeciwnym razie nie używaj wskaźnika, chyba że daje bardzo wyraźną poprawę wydajności" –

1

Jeśli wielkość wskaźnika jest mniejsza niż elementu struct, a następnie za pomocą wskaźnika jest bardziej wydajne, ponieważ nie trzeba kopiować elementu, ale tylko jego adres. Ponadto, jeśli chcesz mieć możliwość przeniesienia lub udostępnienia jakiejś części struktury, lepiej mieć wskaźnik, aby ponownie udostępnić tylko adres członka. Zobacz także golang faqs.

+1

Thx za odpowiedź. Kiedy mówisz o kopii "używanie wskaźnika jest bardziej efektywne, ponieważ nie musisz kopiować elementu, a tylko jego adres", czy jest tak również, nawet jeśli używamy tylko Exp jako wskaźnika, tzn. * Exp? Co więcej, jeśli zdefiniujemy metodę na typ Exp, a nie * Exp, to, co mówisz o kopiach, stosuje się za każdym razem, gdy wywołujemy tę metodę, tj. Istnieje kopia Exp, do której wywoływana jest metoda? (Myślę, że tak po przeczytaniu pedału o definicji metody). – fsenart

+1

Tak, argument typu "Exp" będzie kopiowany za każdym razem. I tak, jeśli masz argument "Exp *", członek nie zostanie skopiowany. Wskaźniki umożliwiają udostępnianie danych i kompaktowe przekazywanie danych. – perreal

+3

Używanie wskaźnika może być bardziej * wydajne * pamięci, ale prawdopodobnie będzie działać gorzej w różnych przypadkach, ponieważ tracisz lokalność danych. Jeśli dane należą do siebie i są często odwiedzane razem, trzymaj je razem. – zmb