2016-02-11 10 views
5

Moje pytanie dotyczy tego, czy kopia wartości jest tworzona po wywołaniu metody, gdy odbiorcą jest _.Czy odbiornik `_` na wartości (non-pointer) nadal kopiuje wartość?

type Foo struct { 
    // Many fields, making a large struct 
} 

func (_ Foo) Test(v *T) int { 
    // Here we can't use the receiver but the method is still needed 
} 

Więc zastanawiam się czy implementacje Go nadal skopiować wartość Foo gdy Test() jest wywoływana, nawet jeśli jest to niemożliwe, aby faktycznie mutować wartość odbiornika.

var f Foo 
f.Test() // Is this making a copy? 

Zastanawiam się również nad przypadkiem wskaźnika, który jest domyślnie automatycznie dereferencji.

var f = new(Foo) 
f.Test() // Is this making a copy? 

Próbowałem spojrzeć na zgromadzenie i myślę, że może to być kopia, ale po prostu nie wiem wystarczająco dużo, aby się upewnić.


Aby uzyskać szczegółowe informacje na temat sytuacji:

To dziwny przypadek, w którym nie mogę użyć wskaźnika. Kod jest generowany maszynowo i jest wymagany do spowodowania, że ​​typ wypełnia interfejs podczas wykonywania inicjalizacji na parametrze v. (Wygenerowany kod zawiera metadane dotyczące Foo że zostanie ustawiony na v.)

Więc jeśli robię odbiornik wskaźnik, interfejs nie zostanie spełnione „wartość” przypadkach. Ta metoda będzie wywoływana raz dla każdej instancji, a instancje mogą czasami być duże i/lub tworzone wielkimi liczbami, dlatego chciałbym uniknąć niepotrzebnej kopii.

+1

mogliśmy sprawdzić poprzez ogromny typ odbiornika ('typ Ogromne [1E5] int' lub cokolwiek), powołując się na metodę jak twoje milion razy i sprawdzanie, czy działa zauważalnie wolniej niż robi to samo z mniejszym typem odbiornika. – twotwotwo

+2

Łańcuch narzędzi gc nie optymalizuje przypadku, w którym argument ma nazwę z pustym identyfikatorem. –

+1

Usuwam odpowiedź, chyba że dostanę czas na sprawdzenie złożenia i zobaczę, jakie są rzeczywiste różnice, ponieważ oszczędność ~ 4ns jest mniejsza niż statystyczny szum jakiejkolwiek prawdziwej pracy. Ogólnie rzecz biorąc, procesory są bardzo szybkie w kopiowaniu, więc nie powinieneś się tym martwić, chyba że twoja struktura jest bardzo duża. W takim przypadku wystarczy użyć wskaźnika, ponieważ nie zapłacisz ceny wyszukiwania, jeśli nie wyłączysz go. – JimB

Odpowiedz

3

Zgodnie z this blog post, wywołujący przydziela elementy stosu dla wartości zwracanych, a wywożony je wypełnia.

To prowadzi mnie do przekonania, że ​​wartość jest kopiowana, a następnie odrzucana.

To lub specjalistycznym wywoływany musiałaby być generowane w przypadku _ odbiornika

+0

Dzięki, tak, to wynika z testowania, że ​​wartość jest rzeczywiście skopiowana.Wydaje się, że bezpieczna optymalizacja pozwala uniknąć kopii, ale ponieważ jest to nietypowa okoliczność, nie dziwi mnie zbytnio, że ta optymalizacja nie istnieje. –

Powiązane problemy