Re[6]: string_view по ссылке или по значению
От: _NN_ www.nemerleweb.com
Дата: 28.05.19 13:34
Оценка:
Z>Вы куда-то контекст обсуждения потеряли.
Z>Естественно функция которую не вызывают вообще самая быстрая,
Z>можно считать что она вызывается за 0 тактов.
Z>Но мы же хотим чтобы в вся программа при использовании того или иного
Z>способа возврата string_view работала быстрее.
Z>Поэтому нужно рассматривать функцию возвращающую string_view вместе
Z>с кодом который ее вызывает.

Z>И я вижу два варианта:


Z>
Z>string_view_ref_or_value get_string_view();

Z>string_view_ref_or_value x = get_string_view();
Z>


Z>либо мы сразу используем x, тогда мы лезем в память и достаем

Z>и data и size (1), или передаем полученный x куда-то, но как мы выяснили
Z>передачу лучше делать по значению, значит мы снова лезем в память и опять же достаем
Z>data и size (2) (можно конечно дальше передавать ссылку, что кстати очень опасно,
Z>но в конце концов мы придем к 1 или 2).
А если мы передаём одни ссылки то нам не нужно доставать data и size до функции, где реально они будут нужны.
Скажем, в цепочке f->g->h->i мы можем создать объект в f и передавать ссылку до i, и только там достать data и size;
Если передавать по значению получается нужно их доставать и передавать каждый раз.
Или есть подвох ?

Z>В обоих случаях получается что либо одинаково быстро будет

Z>работать вся программа или чуть медленнее, если string_view вычисляется,
Z>потому кладется в поле класса, а потом на поле класса возвращается ссылка.

Т.е. если возвращать заранее созданный string_view как в случае поле класса то ссылка будет эффективней чем возвращать по значению ? Так ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[13]: string_view по ссылке или по значению
От: reversecode google
Дата: 28.05.19 13:35
Оценка:
кстати под виндой, 70 шланг релиз выдал два одинаковых результата на x64
по значению как по ссылке
с двумя под чтениями

хз кто там в бекенде кланга генерил обжект
у меня он под студию стоит настроенный
Re[7]: string_view по ссылке или по значению
От: Zhendos  
Дата: 28.05.19 16:09
Оценка:
Здравствуйте, _NN_, Вы писали:


Z>>И я вижу два варианта:


Z>>
Z>>string_view_ref_or_value get_string_view();

Z>>string_view_ref_or_value x = get_string_view();
Z>>


Z>>либо мы сразу используем x, тогда мы лезем в память и достаем

Z>>и data и size (1), или передаем полученный x куда-то, но как мы выяснили
Z>>передачу лучше делать по значению, значит мы снова лезем в память и опять же достаем
Z>>data и size (2) (можно конечно дальше передавать ссылку, что кстати очень опасно,
Z>>но в конце концов мы придем к 1 или 2).
_NN>А если мы передаём одни ссылки то нам не нужно доставать data и size до функции, где реально они будут нужны.
_NN>Скажем, в цепочке f->g->h->i мы можем создать объект в f и передавать ссылку до i, и только там достать data и size;
_NN>Если передавать по значению получается нужно их доставать и передавать каждый раз.
_NN>Или есть подвох ?

Ничего не понял,
если есть цепочка возврата, то какая разница заняты два регистра или один?
каждый раз это просто "ret", зачем кого-то доставать?

"f" заполняет два регистра и вызвает "ret", "g" уже имеет правильно заполненные регистры,
поэтому она просто вызывает ret, как и "h" и "i" сразу их использует.

Z>>В обоих случаях получается что либо одинаково быстро будет

Z>>работать вся программа или чуть медленнее, если string_view вычисляется,
Z>>потому кладется в поле класса, а потом на поле класса возвращается ссылка.

_NN>Т.е. если возвращать заранее созданный string_view как в случае поле класса то ссылка будет эффективней чем возвращать по значению ? Так ?


Нет, будет так же или хуже при возврате по ссылке. Хуже потому что если мы где-то будет иметь код
вида:

const string_view &another_get_string_view()
{
  const string_view& s = get_string_view();
  work_with_s_1(s);
  global_function();
  work_with_s_2(s);
  return s;
}


то так как мы получили "s" по ссылке, то мы два раза перечитаем "data" и "size"
из памяти, так как может global_function поменяла данные по ссылке.

То есть если мы предаем не используя, то есть у нас прямая цепочка
h() { return g(); } g() { return f(); }


то будет также, потому что хотя мы используем два регистра,
а не один, но это ведь "конец" всех этих функций,
и регистры не нужно на стек сохранять,
а если мы между делом, что-то делаем с этим 'const string_view&' то будет хуже.

И как бы нужно не забывать, что string_view это по сути ссылка,
и она может быть получена от std::string,
и чем дальше мы отдаем string_view, тем сложнее следить за временем жизни,
передавать на несколько уровней вверх без использования string_view это
по-моему очень странный сценарий.
Отредактировано 28.05.2019 16:12 Zhendos . Предыдущая версия .
Re[8]: string_view по ссылке или по значению
От: _NN_ www.nemerleweb.com
Дата: 28.05.19 22:05
Оценка:
Здравствуйте, Zhendos, Вы писали:

Z>то будет также, потому что хотя мы используем два регистра,

Z>а не один, но это ведь "конец" всех этих функций,
Z>и регистры не нужно на стек сохранять,
Z>а если мы между делом, что-то делаем с этим 'const string_view&' то будет хуже.

MSVC судя по всему не очень доволен передачей по значению.
Получаем копирование из памяти вместо использование регистров:
        mov     rdi, QWORD PTR __$ReturnUdt$[rsp]
        mov     rsi, rax
        mov     ecx, 16
        rep movsb


https://gcc.godbolt.org/z/bEiWGU
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[9]: string_view по ссылке или по значению
От: Zhendos  
Дата: 28.05.19 23:57
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, Zhendos, Вы писали:


Z>>то будет также, потому что хотя мы используем два регистра,

Z>>а не один, но это ведь "конец" всех этих функций,
Z>>и регистры не нужно на стек сохранять,
Z>>а если мы между делом, что-то делаем с этим 'const string_view&' то будет хуже.

_NN>MSVC судя по всему не очень доволен передачей по значению.


_NN>https://gcc.godbolt.org/z/bEiWGU


1. Не inline бесмысленна в этом коде, функция должна быть extern,
то есть ее тело должно быть невидимым для компилятор в этой единице трансляции
2. Нужно конечно в godbolt поменять компилятор на любой другой: icc, clang, gcc
Ведь в том ABI в x86-64 который реализовала MS весь спор о передаче по ссылке 16 байт
или по значению, а также возврат по ссылке 16 байт или по значению полностью бессмыслен,
разве это не очевидно?
Re[13]: string_view по ссылке или по значению
От: N. I.  
Дата: 29.05.19 08:58
Оценка:
_NN_:

_NN>Мы тут обсуждаем именно подкапотную работу, а не абстракции языка.

_NN>То, что всё передается по значению по умолчанию это свойства языка и никто с этим не спорит, вопрос будет ли это достаточно эффективным в случае string_view или нет.

В случае, когда функция инлайнится, calling conventions ничего не решают.

В случае, когда вызов функции не инлайнится, следует учитывать не только то, каким способом на низком уровне будут переданы аргументы, но ещё и насколько удобно компилятору будет оптимизировать код после такого вызова. Передача аргумента по const reference никак не защищает его от изменения внутри вызываемой функции, т.к. она легально может применить const_cast (если объект изначально не const) и дальше делать с ним что угодно. Когда же локальный объект куда-то передаётся по значению, отследить, что его не модифицируют, заметно проще.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.