карты
C++11/14:
Хеш-таблицы;
Умные указатели;
Многопоточность.
Жгировский Сергей
Яндекс.Карты
С++ party, Минск
Хеш-таблицы
3
Предыдущие реализации
• hash_set, hash_map и др. - расширение языка;
• различные реализации, интерфейсы;
!
• VS: stdext::h...
C++11
std::unordered_set;!
std::unordered_map;!
std::unordered_multiset;!
std::unordered_multimap.
5
std::set;!
std::map;!...
Концептуальноe представление
6
Хеш-таблица (unordered_set)
Красно-чёрное дерево (set)
O(1)!
!
O(1)!
O(1) !
—————
O(1) … O(n)!
!
O(1) … O(n)!
O(1) … O(n)!
—————
Алгоритмическая сложность
7
Хеш-таблица Красно-ч...
rehash
• unordered_*::rehash(size_t bucket_count);!
• Происходит каждый раз при «переполнении»
контейнера 

(заполненность...
Использование
9
template<!
class Key,!
class Hash = std::hash<Key>,!
class KeyEqual = std::equal_to<Key>,!
class Allocator...
std::hash
• основных типов;
• указателей;
• std::string, wstring, u16string,
u32string;!
• std::unique_ptr, std::shared_pt...
std::hash
Для всего остального std::hash не определён:
11
• std::vector<T>, list, deque, array, set,
map, и все остальные ...
Пользовательские типы
class A {!
public:!
bool operator == (const A& rhs) const;!
friend class std::hash<A>;!
!
private:!
...
Пользовательские типы
namespace std {!
template<>!
struct hash<A> {!
size_t operator()(const A& rhs) const {!
size_t val =...
Умные указатели
14
Зачем?
const A* a = new A;!
!
delete a;
!
throw std::exception();!
Базовая реализация
16
template <typename T>!
class smart_ptr!
{!
T* ptr;!
public:!
explicit smart_ptr(T* p) : ptr(p) {}!
~...
Прошлое
std::auto_ptr!
deprecated в С++11
!
17
!
Конструктор копирования:
auto_ptr(auto_ptr& other)!
!
std::auto_ptr<int> ...
Настоящее
18
#include <memory>!
!
std::unique_ptr!
std::shared_ptr!
std::weak_ptr
std::unique_ptr
Замена std::auto_ptr;!
!
auto x = std::unique_ptr<A>(new A);!
auto y = x; // теперь это не компилируется
a...
Функциональность
• можно использовать в контейнерах;
• работает с неполными типами;
• поддерживает указатели на массивы;
•...
Неполные типы
class A {!
public:!
// публичный интерфейс!
!
private:!
// все внутренности спрятаны!
class AImpl;!
smart_pt...
Неполные типы
class A;!
A* a = f();!
delete a; // undefined behaviour
22
Пользовательские
«удаляторы»
template<!
class T,!
class Deleter = std::default_delete<T>!
> class unique_ptr;
23
Пользовательские
«удаляторы»
const Resource* resource = !
acquireResource();!
!
std::unique_ptr<Resource> up(!
! resource,...
Полиморфизм
std::unique_ptr<Base> up(new Derived);!
!
25
!
std::unique_ptr<Base> b;!
std::unique_ptr<Derived> d(new Derive...
std::make_unique (C++14!)
std::unique_ptr<!
TransactionalDataSourceContextBase!
> up(new !
TransactionalDataSourceContextB...
std::make_unique (C++14!)
f(unique_ptr<A>(new A(1,2,3)),!
unique_ptr<B>(new B(1,2)));!
!
auto up = std::make_unique<A>(1,2...
std::shared_ptr
auto x = std::shared_ptr<A>(new A);!
auto y = x; // можно копировать
// A будет удалён, когда последний из...
Концептуальное представление
29
ptr
ref
Object
блок	

подсчёта	

ссылок
shared_ptr	

!
!
!
std::make_shared
30
ptr
ref
Object
блок	

подсчёта	

ссылок
shared_ptr	

!
!
!
Одно выделение памяти (помимо всего прочего...
Многопоточность
31
Что нового
std::thread;!
std::async, std::future;!
mutexes;!
atomics;!
conditional variables;!
thread_local data.
32
std::thread
#include <thread>!
void f();!
!
struct Doer {!
void operator()() const;!
};!
!
int main() {!
std::thread th1(f...
!
!
!
!
!
{ !
std::thread th(...);!
// деструктор:!
join(); detach(); std::terminate(); // ?!
}
деструктор std::thread
34
std::vector<std::future<int>> results;!
for (int i=0; i<10; ++i)!
results.push_back(std::async(heavy_computation));!
!
for...
std::launch::async!
std::launch::deferred!
!
Политика запуска
36
!
!
!
std::async(std::launch::async, heavy_computation);
Деструктор std::future
37
void calculate_asynchronously() {!
std::async(heavy_computation);!
}
Деструктор std::future
38
void calculate_asynchronously() {!
std::async(std::launch::async, heavy_computation);!
std::asyn...
Не оставляйте задачи без
присмотра
39
void calculate_asynchronously() {!
std::future<void> a = std::async(heavy_computatio...
thread_local
40
template<typename Key, typename Value>!
class SmallCachedStorage {!
private:!
thread_local std::unordered_...
Спасибо за внимание!
карты
Жгировский Сергей
!
Яндекс.Карты
разработчик
!
ixanezis@yandex-team.ru
Сергей Жгировский — С++11/14 в STL
Upcoming SlideShare
Loading in …5
×

Сергей Жгировский — С++11/14 в STL

1,299 views

Published on

Речь пойдёт о расширении библиотеки STL в стандарте С++11/C++14. Мы поговорим о новых контейнерах, алгоритмах, многопоточности, умных указателях и других полезных вещах, которые появились в новом стандарте и активно используются в Яндексе.

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,299
On SlideShare
0
From Embeds
0
Number of Embeds
755
Actions
Shares
0
Downloads
9
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Сергей Жгировский — С++11/14 в STL

  1. 1. карты C++11/14: Хеш-таблицы; Умные указатели; Многопоточность. Жгировский Сергей Яндекс.Карты С++ party, Минск
  2. 2. Хеш-таблицы 3
  3. 3. Предыдущие реализации • hash_set, hash_map и др. - расширение языка; • различные реализации, интерфейсы; ! • VS: stdext::hash_set;! • GCC: __gnu_cxx::hash_set; ! • C 2007: std::tr1::unordered_set, -map, ... 4
  4. 4. C++11 std::unordered_set;! std::unordered_map;! std::unordered_multiset;! std::unordered_multimap. 5 std::set;! std::map;! std::multiset;! std::multimap.
  5. 5. Концептуальноe представление 6 Хеш-таблица (unordered_set) Красно-чёрное дерево (set)
  6. 6. O(1)! ! O(1)! O(1) ! ————— O(1) … O(n)! ! O(1) … O(n)! O(1) … O(n)! ————— Алгоритмическая сложность 7 Хеш-таблица Красно-чёрное дерево O(log n)! ! O(log n)! O(log n)! O(log n) insert! ! erase! find! lower,upper_bound Амортизационная оценка
  7. 7. rehash • unordered_*::rehash(size_t bucket_count);! • Происходит каждый раз при «переполнении» контейнера 
 (заполненность = size() / bucket_count() ); • nextprime(2 * bucket_count()); // GCC only • O(n) … O(n2). 8
  8. 8. Использование 9 template<! class Key,! class Hash = std::hash<Key>,! class KeyEqual = std::equal_to<Key>,! class Allocator = std::allocator<Key>! > class unordered_set;
  9. 9. std::hash • основных типов; • указателей; • std::string, wstring, u16string, u32string;! • std::unique_ptr, std::shared_ptr;! • std::error_code, std::thread::id;! • std::bitset, std::vector<bool>. 10 В библиотеке присутствует специализация для:
  10. 10. std::hash Для всего остального std::hash не определён: 11 • std::vector<T>, list, deque, array, set, map, и все остальные контейнеры; • std::pair<T1, T2>, std::tuple<...>.
  11. 11. Пользовательские типы class A {! public:! bool operator == (const A& rhs) const;! friend class std::hash<A>;! ! private:! int x_;! std::string y_;! }; 12
  12. 12. Пользовательские типы namespace std {! template<>! struct hash<A> {! size_t operator()(const A& rhs) const {! size_t val = 0;! val += hash<int>()(rhs.x_) * 31;! val += hash<string>()(rhs.y_) * 59;! // boost::hash_combine! return val;! }! };! } 13
  13. 13. Умные указатели 14
  14. 14. Зачем? const A* a = new A;! ! delete a; ! throw std::exception();!
  15. 15. Базовая реализация 16 template <typename T>! class smart_ptr! {! T* ptr;! public:! explicit smart_ptr(T* p) : ptr(p) {}! ~smart_ptr() { delete ptr; }! };!
  16. 16. Прошлое std::auto_ptr! deprecated в С++11 ! 17 ! Конструктор копирования: auto_ptr(auto_ptr& other)! ! std::auto_ptr<int> x = y; // y пуст
  17. 17. Настоящее 18 #include <memory>! ! std::unique_ptr! std::shared_ptr! std::weak_ptr
  18. 18. std::unique_ptr Замена std::auto_ptr;! ! auto x = std::unique_ptr<A>(new A);! auto y = x; // теперь это не компилируется auto z = std::move(x); // зато работает перемещение 19
  19. 19. Функциональность • можно использовать в контейнерах; • работает с неполными типами; • поддерживает указатели на массивы; • пользовательские «удаляторы»; • поддерживает полиморфизм; 20
  20. 20. Неполные типы class A {! public:! // публичный интерфейс! ! private:! // все внутренности спрятаны! class AImpl;! smart_ptr<AImpl> impl_;! }; 21
  21. 21. Неполные типы class A;! A* a = f();! delete a; // undefined behaviour 22
  22. 22. Пользовательские «удаляторы» template<! class T,! class Deleter = std::default_delete<T>! > class unique_ptr; 23
  23. 23. Пользовательские «удаляторы» const Resource* resource = ! acquireResource();! ! std::unique_ptr<Resource> up(! ! resource,! ! releaseResource);! // ресурс будет удалён, когда ‘up’ выйдет! // из области действия либо в случае любых! исключений 24
  24. 24. Полиморфизм std::unique_ptr<Base> up(new Derived);! ! 25 ! std::unique_ptr<Base> b;! std::unique_ptr<Derived> d(new Derived);! b = std::move(d);
  25. 25. std::make_unique (C++14!) std::unique_ptr<! TransactionalDataSourceContextBase! > up(new ! TransactionalDataSourceContextBase(1,2,3)); 26
  26. 26. std::make_unique (C++14!) f(unique_ptr<A>(new A(1,2,3)),! unique_ptr<B>(new B(1,2)));! ! auto up = std::make_unique<A>(1,2,3); 27
  27. 27. std::shared_ptr auto x = std::shared_ptr<A>(new A);! auto y = x; // можно копировать // A будет удалён, когда последний из владеющих им объектов будет удалён ! auto z = std::move(x); // перемещение также продолжает работать, если не хотим копировать. 28 разделяемое владение объектом;
  28. 28. Концептуальное представление 29 ptr ref Object блок подсчёта ссылок shared_ptr ! ! !
  29. 29. std::make_shared 30 ptr ref Object блок подсчёта ссылок shared_ptr ! ! ! Одно выделение памяти (помимо всего прочего) Exception safe «We know were you live» optimization
  30. 30. Многопоточность 31
  31. 31. Что нового std::thread;! std::async, std::future;! mutexes;! atomics;! conditional variables;! thread_local data. 32
  32. 32. std::thread #include <thread>! void f();! ! struct Doer {! void operator()() const;! };! ! int main() {! std::thread th1(f); // сразу же начинает работать! std::thread th2(Doer{});! std::thread th3([]{ ... });! ! th1.join(); th2.join(); th3.join();! ! return 0;! } 33
  33. 33. ! ! ! ! ! { ! std::thread th(...);! // деструктор:! join(); detach(); std::terminate(); // ?! } деструктор std::thread 34
  34. 34. std::vector<std::future<int>> results;! for (int i=0; i<10; ++i)! results.push_back(std::async(heavy_computation));! ! for (auto& f : results)! std::cout << f.get() << std::endl; Асинхронные задачи 35
  35. 35. std::launch::async! std::launch::deferred! ! Политика запуска 36 ! ! ! std::async(std::launch::async, heavy_computation);
  36. 36. Деструктор std::future 37 void calculate_asynchronously() {! std::async(heavy_computation);! }
  37. 37. Деструктор std::future 38 void calculate_asynchronously() {! std::async(std::launch::async, heavy_computation);! std::async(std::launch::async, heavy_computation2);! // не параллельно!! }
  38. 38. Не оставляйте задачи без присмотра 39 void calculate_asynchronously() {! std::future<void> a = std::async(heavy_computation);! auto b = std::async(heavy_computation2);! a.get();! b.get();! }
  39. 39. thread_local 40 template<typename Key, typename Value>! class SmallCachedStorage {! private:! thread_local std::unordered_map<Key, Value> cached_;! ! public:! Value calculate(const Key& key); // cached! };! boost::thread_specific_ptr<T>;!
  40. 40. Спасибо за внимание!
  41. 41. карты Жгировский Сергей ! Яндекс.Карты разработчик ! ixanezis@yandex-team.ru

×