Шаг отладки в g++
6.4 stdlibc ++ source
Знаете ли вы, что в пакете g++-6
Ubuntu по умолчанию 16.04 или в сборке GCC 6.4 из источника вы можете войти в библиотеку C ++ без дальнейшей настройки?
Делая это, мы легко заключаем, что красно-черное дерево используется в этой реализации.
Это имеет смысл, поскольку std::set
можно пройти по порядку, что было бы неэффективно в случае использования хэш-карты.
main.cpp
#include <cassert>
#include <set>
int main() {
std::set<int> s;
s.insert(1);
s.insert(2);
assert(s.find(1) != s.end());
assert(s.find(2) != s.end());
assert(s.find(3) == s3.end());
}
Компиляция и отладка:
g++ -g -std=c++11 -O0 -o main.out main.cpp
gdb -ex 'start' -q --args main.out
Теперь, если вы войдете в s.insert(1)
, вы сразу достигнете /usr/include/c++/6/bits/stl_set.h
:
487 #if __cplusplus >= 201103L
488 std::pair<iterator, bool>
489 insert(value_type&& __x)
490 {
491 std::pair<typename _Rep_type::iterator, bool> __p =
492 _M_t._M_insert_unique(std::move(__x));
493 return std::pair<iterator, bool>(__p.first, __p.second);
494 }
495 #endif
, который явно просто переходит к _M_t._M_insert_unique
.
Итак, мы открываем исходный файл в vim и находим определение _M_t
:
typedef _Rb_tree<key_type, value_type, _Identity<value_type>,
key_compare, _Key_alloc_type> _Rep_type;
_Rep_type _M_t; // Red-black tree representing set.
То есть _M_t
имеет тип _Rep_type
, а _Rep_type
является _Rb_tree
.
Хорошо, теперь для меня достаточно доказательств. Если вы не верите, что _Rb_tree
- это черно-красное дерево, сделайте шаг вперед и прочтите алгоритм.
unordered_set
использует хэш-таблицу
Та же процедура, но замените set
на unordered_set
в коде.
Это имеет смысл, поскольку std::unordered_set
не может быть пройден по порядку, поэтому стандартная библиотека выбрала хэш-карту вместо красно-черного дерева, поскольку хэш-карта имеет более высокую амортизированную сложность времени вставки.
Шаг insert
ведет к /usr/include/c++/6/bits/unordered_set.h
:
415 std::pair<iterator, bool>
416 insert(value_type&& __x)
417 { return _M_h.insert(std::move(__x)); }
Итак, мы открываем исходный файл в vim
и ищем _M_h
:
typedef __uset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable;
_Hashtable _M_h;
Итак, хэш-таблица.
std::map
и std::unordered_map
Аналогично std::set
против std:unordered_set
: Какая структура данных находится внутри std :: map в C ++?
Характеристики производительности
Вы можете также вывести структуру данных, используемую для их синхронизации:
![enter image description here](https://i.stack.imgur.com/2Kcl0.png)
Процедура генерации графика и анализ кучи против BST и по адресу: Куча против дерева двоичного поиска (BST)
Мы ясно видим для: