Comments 23
Reference-counted std::string запрещён в C++11.
www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2534.html
www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2534.html
Да, похоже не то. В стандарте по этому пункту особо разбираться не стал, ведь на всех трех компиляторах, где я запускал этот код в режиме --std=c++11 подсчет ссылок присутствовал.
Буду благодарен, если подскажете как его отключить.
Буду благодарен, если подскажете как его отключить.
Мм, тут подсказывают что строки, совместимые с с++11 появятся в следующей версии библиотеки. А в текущей версии совместимыми являются __gnu_cxx::__versa_string из #include <ext/vstring.h>. Сразу же попробовал но похоже меня постигло разочарование :( в __versa_string используютя анонимные объединения, не позволяющие использовать в качестве символов типы имеющие конструктор. Но как оказалось это можно с -std=gnu++11 и таки да, подсчет ссылок отключился.
а вы не забыли о char_traits<>? www.cplusplus.com/reference/string/char_traits/
они определяют часть низкоуровневых ф-ий со строкой
они определяют часть низкоуровневых ф-ий со строкой
Нет не забыл. char_traits определяют операции с символами и массивами символов. Ну и он параметризируемый. Т.е. basic_string использутет трайт char_traits. Вот вам пример из файла 4.7.2/bits/char_traits.h реализация одного из 14 методов структуры char_traits.
Тут будет использован
Ну и кроме того, если бы были какие-либо несоответствия с операциями, то код бы просто не компилировался.
static _GLIBCXX_CONSTEXPR bool
lt(const char_type& __c1, const char_type& __c2)
{ return __c1 < __c2; }
Тут будет использован
operator<(const X&)
.Ну и кроме того, если бы были какие-либо несоответствия с операциями, то код бы просто не компилировался.
Заполняющий конструктор так вообще удивил — откуда-то взялись дополнительные копирования и деструкторы.Они взялись из-за передачи трассера по значению в подпрограммы. Что характерно, если бы тип НЕ был трассером, то компилятор все оптимизировал бы и заинлайнил, и никаких дополнительных копирований не происходило бы.
Неожиданно, результат для resize получился значительно хуже чем для reserveДля меня — ожидаемо.
reserve меняет размер выделенного под строку буфера, но не меняет саму строку.
resize же меняет длину строки, для чего должен дописать в конец нужное число символов.
деструкторы для символов не вызываются
А типа, должны были бы?
Мне кажется, у вас вообще результаты получились сильно далеки от правды из-за того, что компилятор не оптимизировал (или по-другому оптимизировал) обращение с классом — с элементарным типом char там может всё совсем по-другому быть.
Для полноценного контейнера должны были, а для строки мне было неизвестно. Теперь ясно, что не вызываются.
Тут не в оптимизации одного алгоритма, дело в сравнении двух. Если количество операций в неоптимизированном варианте меньше, то после оптимизации скорее всего быстрее будет алгоритм с меньшим количеством операций.
Да, возможно всякие выравнивания и детали реализации съедят разницу в скоростях, но зато подсчет операций трассером не завист ни от платформы, ни от уровня оптимизации.
Тут не в оптимизации одного алгоритма, дело в сравнении двух. Если количество операций в неоптимизированном варианте меньше, то после оптимизации скорее всего быстрее будет алгоритм с меньшим количеством операций.
Да, возможно всякие выравнивания и детали реализации съедят разницу в скоростях, но зато подсчет операций трассером не завист ни от платформы, ни от уровня оптимизации.
Таки до конца не осознал, надо еще пару раз перечитать.
Первый аспект который я не понял. class X это заменитель типа char? т.е. в строке
xs s1((X*)«1234567890»);,
X* x = (X*) «1234567890», x будет воспринят как указатель на массив из элементов X?
Еще я немного удивлен тем что не используются операции типа memcpy для копирования _CharT* _M_p.
Первый аспект который я не понял. class X это заменитель типа char? т.е. в строке
xs s1((X*)«1234567890»);,
X* x = (X*) «1234567890», x будет воспринят как указатель на массив из элементов X?
Еще я немного удивлен тем что не используются операции типа memcpy для копирования _CharT* _M_p.
class X — это заменитель char, бинарно совместимый с ним. Вся его полезная нагрузка — это подсчет вызовов конструкторов, деструкторов и прочих операций.
А операции типа memcpy для копирования X не используются, поскольку не указаны в общей реализации char_traits. Операции над строкой char, конечно же, ускоряются.
А операции типа memcpy для копирования X не используются, поскольку не указаны в общей реализации char_traits. Операции над строкой char, конечно же, ускоряются.
А пробовали сравнивать различные std библиотеки? Я на вскидку знаю три, умеющих С++11, это libstdc++ из gcc, libcxx из clang и msvcшная реализация, которая глубоко привязана к компилятору.
Локально не пробовал. Однако, тут есть сервис предлагающий компиляцию разными компиляторами (g++,intel,clang) врядли они используют одну и ту же реализацию, хотя не факт конечно. Так вот, на этом сервисе результаты у этих трех компиляторов одинаковые.
msvc у меня нет, возможно кто-нибудь из хабраюзеров сможет скачать исходник и выложить тут получившуюся табличку(она прям в html генерится).
msvc у меня нет, возможно кто-нибудь из хабраюзеров сможет скачать исходник и выложить тут получившуюся табличку(она прям в html генерится).
Потому, что надо вот так собирать
Но тот сервис такое не поддерживает. А без этого флага они все три используют libstdc++
-std=c++11 -Wall -W -pedantic -O2 -stdlib=libc++
Но тот сервис такое не поддерживает. А без этого флага они все три используют libstdc++
Ясно, спасибо. Как настрою у себя clang — выложу результат.
C нативной clang библиотекой не собирается:
$ clang++ -std=c++11 -Wall -W -pedantic -O2 -stdlib=libc++ ./test.cpp
/usr/include/c++/v1/string:1134:31: error: attempt to use a deleted function
_LIBCPP_INLINE_VISIBILITY basic_string()
...
fatal error: too many errors emitted, stopping now
msvc из vs2012:
error C2621: member 'std::_String_val<_Val_types>::_Bxty::_Buf' of union 'std::_String_val<_Val_types>::_Bxty' has copy constructor
with
[
_Val_types=std::_Simple_types<tracer::X>
]
У вас в методике тестирования принципиально заложен undefined behavior. Читаем C++11 [strings]:
> This Clause describes components for manipulating sequences of any non-array POD (3.9) type.
Ваш класс совсем не POD. Поэтому все измерения не имеют никакого смысла, это всё UB.
> This Clause describes components for manipulating sequences of any non-array POD (3.9) type.
Ваш класс совсем не POD. Поэтому все измерения не имеют никакого смысла, это всё UB.
а в какой главе «C++ Templates: The Complete Guide» написано про трассировщик?
6.6.4 Tracers
Sign up to leave a comment.
Несколько подробностей об std::string