Guest User

Untitled

a guest
Apr 11th, 2021
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.66 KB | None | 0 0
  1. СПИСКИ ВСЕХ СОРТОВ
  2. ===================
  3.  
  4. Самая короткая, скучная и бесполезная лекция!!!
  5.  
  6. Внезапно, про партиклы!
  7. * emit()
  8. * update()
  9. * die()
  10. * И на каждом шаге случайность.
  11.  
  12. Базовая наука.
  13. * Когда и зачем?
  14. * Зачем ваще (аллокатор, партиклы).
  15. 1) когда надо более-менее гарантированное худшее время вставки и удаления (или тупо более лучше, чем в другой структуре)... или просто перемещения (!!!) объекта в другое место по списку. Примеры == аллокатор (в широком смысла), MTF.
  16. 2) когда нужно поддерживать 1 и более порядков (зачастую дополнительных) твоих объектов (строчки конфига в порядке появления, объекты в кеше по размеру, по времени обращения, по типу, итд итп). Примеры == my_ordered_hash.
  17. * Одно-двух связные, интрузивные-нет, указатели-индексы (привет FAT).
  18. - одно == next, двух == prev+next
  19. - интрузивные == myclass::next, не == std::list<myclass>::value
  20. ! int next, int prev поверх массива либо вектора, и это тоже будет список (а в сложном случае и вообще int next_bucket, int next_element)
  21. ! int fat32next[N], где N это число кластеров на флешке
  22.  
  23. Немного трюков.
  24. * Трюк про скип-листы. Два варианта.
  25. - Раз, можно entry *heads[L] и понеслась.
  26. - Два, можно struct entry { VALUE val; entry *next; entry *nextS; ... }.
  27. - В обоих случаях выходят "многоуровневые" списки.
  28. - Типа проще, чем сбалансированное дерево.
  29. - IMHO, эзотеричны и требуются довольно редко.
  30. * Ещё один (уже известный) трюк про MTF, Move To Front. Cache with LRU element eviction == в чистом виде MTF (и ликвидация хвоста списка).
  31. * Ещё считаем оверхеды.
  32. - или, другими словами, где можно неожиданно круто наколоться
  33. 1) каждое обращение к следующему элементу в общем случае dereference, потенциально медленно
  34. 2) в случае с "плохим" разлетом элементов списка по памяти можно внезапно приехать в постоянный cache invalidation (хотя этот эффект проще всего воспроизвести, на самом деле, на векторе!)
  35. * Ещё один (уже известный) трюк про prefetch. Чаще не работает. Когда работает, может работать очень хорошо. Гуглить _mm_prefetch().
  36. * Ещё один трюк про XOR-list.
  37. - Вместо { entry *prev; entry *next; }
  38. - Делаем { entry *prev_xor_next; }
  39. - Но зато ничего не можем сделать, если пришли в ноду не обходом!!!
  40. * Ещё один трюк про группировку мелких объектов из списка (но это про кеш).
  41. - Вместо malloc() делаем
  42. - Или alloc_in_group()
  43. - Или alloc_group()
  44. - Юзкейс "партиклы"
  45. * Ещё трюк про sentinel nodes ("втыкаем внезапный NULL").
  46.  
  47. * std::bugs (в один поток почти нет, а многопоточка тяжело). В смысле, многопоточка без блокировок: lockfree списки вроде как у некоторых работают, но получаются тяжело.
  48. * std::puzzle!
  49. 1) разверните 1-связный список. http://stackoverflow.com/questions/1801549/how-to-reverse-a-singly-linked-list-using-only-two-pointers
  50. 2) найдите цикл в 1-связном списке. (Точнее, установите, есть ли в списке цикл.) За O(1) по памяти! И за O(n) по времени. Красивое решение: запускаем два итератора entry *fast, *slow; fast = fast->next->next; slow = slow->next. Алгоритм Флойда.
  51.  
  52. --eof--
  53.  
  54.  
Advertisement
Add Comment
Please, Sign In to add comment