Причина, що мені так подобається Rcpp, полягає в тому, що я не завжди розумію, як думає R Core, а з Rcpp, найчастіше, мені не доводиться.
Якщо говорити по-філософськи, ви перебуваєте у гріху щодо функціональної парадигми, яка намагається забезпечити, щоб кожна цінність виглядала незалежною від будь-якої іншої цінності; зміна одного значення ніколи не повинна спричиняти видимих змін у іншому значенні, як ви отримуєте вказівники, що діляться представленням у C.
Проблеми виникають, коли функціональне програмування сигналізує малому кораблю про те, щоб рухатись із шляху, а маленьке судно відповідає "Я маяк". Внесення довгих серій невеликих змін до великого об’єкта, який ви хочете обробити тим часом, ставить вас на територію маяка.
У С ++ STL push_back()
- це спосіб життя. Він не намагається бути функціональним, але він дійсно намагається пристосувати загальні ідіоми програмування ефективно .
Маючи кмітливість за лаштунками, іноді можна домовитись, щоб мати одну ногу в кожному світі. Файлові системи на основі знімків є хорошим прикладом (який розвинувся з таких понять, як з'єднання кріплення, які також є обома сторонами).
Якщо R Core хотів це зробити, базове векторне зберігання може функціонувати як з'єднання з'єднання. Одне посилання на векторне сховище може бути дійсним для підписок 1:N
, тоді як інше посилання на те саме сховище справедливе для підписок 1:(N+1)
. Тут може бути зарезервоване сховище, на яке ще не вірно посилається нічого, але зручне для швидкого push_back()
. Ви не порушуєте функціональну концепцію при додаванні за межі діапазону, який будь-яка існуюча посилання вважає дійсною.
Згодом додаючи рядки поступово, у вас закінчується зарезервоване сховище. Вам потрібно буде створити нові копії всього, при цьому обсяг пам’яті помножиться на деякий приріст. Реалізації STL, які я використовую, як правило, примножують сховище на 2 при розширенні розподілу. Я подумав, що я прочитав в "Внутрішній", що існує структура пам'яті, де збільшення сховища на 20%. Так чи інакше, операції з ростом відбуваються з логарифмічною частотою відносно загальної кількості доданих елементів. На амортизованій основі це, як правило, прийнятно.
По мірі хитрощів за лаштунками я бачив і гірше. Кожен раз, коли ви push_back()
вставляєте новий рядок у кадр даних, потрібно буде скопіювати структуру індексу верхнього рівня. Новий рядок може додаватися до спільного представлення, не впливаючи на старі функціональні значення. Я навіть не думаю, що це значно ускладнить сміттєзбірник; оскільки я не пропоную push_front()
всі посилання - це префіксні посилання на передню частину виділеного векторного сховища.
append()
[який, ймовірно, повинен бути названий вставкою] абоc()
додати елементи до кінця списку, хоча тут вам не допоможуть.