Advertisement
Guest User

Untitled

a guest
Apr 11th, 2021
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.54 KB | None | 0 0
  1. ВСЕМ "ИЗВЕСТНЫЕ" АЗЫ
  2. =====================
  3.  
  4. Начнем, как положено, с терминологии!
  5. * Массив, array. Он же статический массив. Это int x[N]. Либо int *x.
  6. * Вектор, vector. Он же динамический массив. class { int *data, length, capacity; } тащемта.
  7. * В других языках и прочем CS все иначе (см. Java, C#, и разумеется PHP), здесь вроде так.
  8.  
  9. Зачем вообще нужны вектора?
  10. * int x[16] vs alloca(64) vs malloc(64)
  11. * int x[16] - быстрое; sub esp,64
  12. * alloca(64) - быстрое; sub esp,64
  13. * malloc(64) - как ни суй, как ни ворочай, (сильно) более 1 инструкции
  14. => локальный мелкий буфер ВСЕГДА быстрее vector!
  15.  
  16. Вектор == зачем?
  17. * "Медленно", безопасно, с оверхедами.
  18. * Про оверхеды: можно играться в спецмакросы даже в отладочных билдах.
  19. * Иии главное: ПРОСТО. Просто берешь и пишешь код.
  20. * Без дурацких len++ или resize() вручную.
  21.  
  22. Какие виды векторов нам вообще нужны?
  23. 1. Труёвый динамический, std::vector classic
  24. 2. Фиксированный размер, но с проверками, std::array, а до того eastl::fixed_vector
  25. * Обратите внимание, с динамичностью размер НЕ связан!
  26. * Говорят, std::array<T,N>, то есть нединамичный совсем никак
  27. * Точно знаю, иногда надо my::fixed_vector v(x) во втором смысле ("где данные лежат") динамичный
  28. + Как всегда, гибриды рулят, чтобы поменьше аллокаций
  29.  
  30. Пишем свой первый условно "полезный" вектор вообще за 1 минуту:
  31.  
  32. template<typename T>
  33. class super_simple_vector {
  34. public: // в нормальном, конечно, protected!
  35. T * data;
  36. int max_capacity;
  37. int cur_length;
  38. public:
  39. T & operator[](int index) {
  40. // !!! вот она, радость-то! (ну или половина радости)
  41. assert(index >= 0 && index < cur_length);
  42. return data[index];
  43. }
  44. };
  45.  
  46. Спорный (?) тезис #1
  47. * 99% времени нужно условных 3 метода
  48. * ctor, dtor, push_back, erase
  49. * в остальных 95% случаев operator[]
  50. * вроде и всё!!!
  51.  
  52. Понятное дело, нужно ещё всякое:
  53. * resize, clear, reserve
  54. * возможно, варианты конструкторов
  55. * наверняка копирование (и оператором и конструктором)
  56. * move semantics для любителей (я не они)
  57. * если наконец C++11, то всякие begin()/end() итп
  58. * всё равно, утверждаю, что ~99% вызовов будет не про них :)
  59.  
  60. Спорный (?) тезис #2
  61. * Ключевой "параметр" у вектора примерно один
  62. * Resize policy!
  63. ??? Со скольки элементов начинаем вектор? - 0, 1, 3, 4, 8, ... интуитивно, 4-32 довольно хорошо
  64. ??? Как подращиваем, когда кончилось? - *sqrt(2), *1.5, *2, ... внезапно! *1.2 для особо больших. Очевидно, любая конкретная константа в каком-то случае ПЛОХА И ВРЕДНА.
  65. ??? Скукоживаемся ли автоматически вниз, или как обычно? - наверное нет!!!
  66.  
  67. Спорный (?) тезис #3
  68. * Стандарт необязателен ("it's more of a guideline")
  69. * Стандарт не всеобъемлющ
  70. * Зачем вам вообще именно итераторы?
  71. * Что у вас в реалиях с инициализацией?
  72. * Честный нудный .emplace_back() или грязный хак .add()?
  73. * Как насчет .addn(int n)?
  74. - memcpy(buf.addn(len), ptr, len)
  75.  
  76. Развлечение для гиков #1
  77. ??? В каком порядке укладывать поля?
  78.  
  79. Развлечение для гиков #2
  80. ??? Попробовать автоматически "скукоживаться" (то есть reclaim-ить память)
  81.  
  82. struct hybrid_vector {
  83. T * data;
  84. int max_capacity;
  85. int cur_length;
  86. T * big_buffer; // можно выкинуть. if (data != small...)
  87. T small_buffer[32]; // дискуссионный вопрос!
  88. };
  89.  
  90. Ура, теперь мы знаем всё.
  91. Что ещё хочется рассказать про массивы и вектора?
  92. * Напоминаю, массивы БЫСТРЕЕ. История про int *out вместо vector<int>.
  93. * Напоминаю, C vs Pascal (terminator vs length) иногда работает.
  94. * Напоминаю, SSO/SCO. Иногда аллокатор это решает; а иногда нет.
  95.  
  96. А ещё бывают стандартные баги.
  97. И в реализации, и в использовании, и функционально, и про перф.
  98.  
  99. Про реализацию:
  100. * POD vs non-POD
  101. * Политика resize
  102. * Политика инициализации
  103. * [censored] [top-secret]
  104.  
  105. Про использование:
  106. * int *ptr = &vec[123]; vec.push_back(456); // oops, crash
  107. * for(;;) { ...; vec.clear(); } // oops, realloc NOT guaranteed
  108. * for(;;) { ...; myvec.reset(); } // oops, realloc guaranteed
  109. * Да, shrink_to_fit(). Нет, клевещут, non-binding.
  110. * for(;;) { vec.reserve(vec.size() + 1); ... } // oops, O(N^2)
  111. * А ещё клевещут, reserve() + push_back() vs new + assign не очень!
  112.  
  113. А ещё бывают совсем странные реализации.
  114. * Chunked non-contiguous гибриды, чтобы manageable куски
  115. * Разреженные массивы (это внезапно KV и сразу Judy arrays)
  116.  
  117. ЧЕМУ МЫ НАУЧИЛИСЬ СЕГОДНЯ?
  118. ---------------------------
  119.  
  120. * Свой вектор это совсем-совсем нехитро.
  121. * Взгреть STL в отдельном месте совсем-совсем нетяжело.
  122. * Всё дело в волшебных "частных" случаях!
  123.  
  124. --eof--
  125.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement