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.
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
Łańcuch narzędzi gc nie optymalizuje przypadku, w którym argument ma nazwę z pustym identyfikatorem. –
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