Czy powinniśmy przekazać współdzielony PST według referencji czy wartości?
Gdy funkcja przyjmuje shared_ptr
(z boost lub C++11 STL), czy przekazujesz ją:
Autor: const reference:
void foo(const shared_ptr<T>& p)
Lub według wartości:
void foo(shared_ptr<T> p)
?
8 answers
To pytanie zostało omówione i udzielone przez Scotta, Andrei i Herba podczas zadaj nam cokolwiek sesja w C++ i poza 2011. Oglądaj z 4min 34sec na shared_ptr
wydajność i poprawność .
Krótko mówiąc, nie ma powodu, aby przekazywać wartość, chyba że celem jest współwłasność obiektu (np. pomiędzy różnymi strukturami danych lub między różnymi wątkami).
Chyba, że możesz przenieść-zoptymalizować to, jak wyjaśnił Scott Meyers w dyskusja wideo podlinkowane powyżej, ale to jest związane z rzeczywistą wersją C++ można użyć.
Duża aktualizacja tej dyskusji miała miejsce podczas GoingNative 2012 panelu interaktywnego konferencji : zapytaj nas o cokolwiek! które warto obejrzeć, zwłaszcza z 22:50.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-24 18:00:47
Wytyczna: nie przekazuj inteligentnego wskaźnika jako parametru funkcji, chyba że chcesz używać lub manipulować samym inteligentnym wskaźnikiem, na przykład udział lub przeniesienie własności.
Wytyczna: wyrażenie, że funkcja będzie przechowywać i dzielić własność obiekt heap za pomocą parametru shared_ptr.
Wytyczna: użyj a non - const shared_ptr & parametr tylko do modyfikacji shared_ptr. Użyj a const shared_ptr & as a parametr tylko wtedy, gdy nie jesteś pewien, czy lub nie będziesz wziąć kopię i współwłasność; w przeciwnym razie użyj widżetu* zamiast tego (lub jeśli nie nullable, widżet&).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-04 21:23:20
Osobiście użyłbym const
referencji. Nie ma potrzeby zwiększania liczby referencji tylko po to, aby ponownie ją zmniejszyć w celu wywołania funkcji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-16 18:44:56
/ Align = "left" / Jeśli chcesz go przechowywać, powiedzmy w jakimś pojemniku, ref. licznik będzie automatycznie zwiększany przez operację kopiowania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 15:54:46
Uruchomiłem poniższy kod, raz z foo
Biorąc shared_ptr
przez const&
i ponownie z foo
Biorąc shared_ptr
przez wartość.
void foo(const std::shared_ptr<int>& p)
{
static int x = 0;
*p = ++x;
}
int main()
{
auto p = std::make_shared<int>();
auto start = clock();
for (int i = 0; i < 10000000; ++i)
{
foo(p);
}
std::cout << "Took " << clock() - start << " ms" << std::endl;
}
Korzystanie z VS2015, X86 release build, na moim procesorze intel Core 2 quad (2.4 GHz)
const shared_ptr& - 10ms
shared_ptr - 281ms
Wersja copy by value była o rząd wielkości wolniejsza.
Jeśli wywołujesz funkcję synchronicznie z bieżącego wątku, wybierz wersję const&
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-26 14:16:48
Od C++11 powinieneś wziąć go przez wartość nad const& częściej niż mogłoby się wydawać.
Jeśli bierzesz STD:: shared_ptr (zamiast bazowego typu T), robisz to, ponieważ chcesz coś z nim zrobić.
Jeśli chcesz skopiować gdzieś , bardziej sensowne jest zabranie go przez copy, a std::przenieś go wewnętrznie, zamiast wziąć go przez const&, a następnie skopiować. Dzieje się tak dlatego, że pozwalasz rozmówcy na opcję w włącz std:: przenieś shared_ptr podczas wywoływania funkcji, zachowując w ten sposób zestaw operacji przyrostowych i przyrostowych. Albo i nie. Oznacza to, że wywołujący funkcję może zdecydować, czy potrzebuje std::shared_ptr po wywołaniu funkcji i w zależności od tego, czy się przesunie, czy nie. Nie jest to osiągalne, jeśli przejdziesz przez const&, a zatem najlepiej jest wziąć go według wartości.
Oczywiście, jeśli wywołujący potrzebuje swojego shared_ptr na dłużej (więc nie może std:: move it) i nie chcesz tworzyć zwykłej kopii w funkcji (powiedzmy, że chcesz słaby wskaźnik lub tylko czasami chcesz go skopiować, w zależności od jakiegoś warunku), wtedy const& może być nadal preferowany.
Na przykład, powinieneś zrobić
void enqueue(std::shared<T> t) m_internal_queue.enqueue(std::move(t));
Over
void enqueue(std::shared<T> const& t) m_internal_queue.enqueue(t);
Ponieważ w tym przypadku zawsze tworzysz kopię wewnętrznie
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-21 12:26:18
Nie znając kosztu czasu operacji kopiowania shared_copy gdzie jest inkrement i dekrement atomowy, cierpiałem na znacznie większy problem z użyciem procesora. Nigdy nie spodziewałem się, że przyrost atomowy i spadek może wymagać tak dużych kosztów.
Po moim wyniku testu, int32 przyrost atomowy i zmniejszanie trwa 2 lub 40 razy niż przyrost i zmniejszanie niematomiczne. Mam go na 3GHz Core i7 z Windows 8.1. Pierwszy wynik wychodzi, gdy nie występuje spór, drugi, gdy duża możliwość występuje spór. Mam na uwadze, że operacje atomowe są w końcu blokadą sprzętową. Zamek to zamek. Złe do wydajności, gdy występuje niezgodność.
Doświadczając tego, zawsze używam byref (const shared_ptr&) niż byval (shared_ptr).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-17 23:27:04
Shared_ptr nie jest wystarczająco duży, ani jego konstruktor\destructor nie wykonuje wystarczająco dużo pracy, aby nie było wystarczająco dużo narzutu z kopii, aby dbać o wydajność pass by reference vs pass by copy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 17:09:08