Я нашел такую строку в каком-то коде Rebol:
dups: make block! 10000
Зачем вам использовать предварительное распределение в Rebol?
Что плохого в том, чтобы просто написать:
dups: copy []
Я нашел такую строку в каком-то коде Rebol:
dups: make block! 10000
Зачем вам использовать предварительное распределение в Rebol?
Что плохого в том, чтобы просто написать:
dups: copy []
Во-первых: вы не «выделяете переменную» в Rebol, вы «предварительно выделяете буфер серии» (на который ссылается слово в вашем примере кода, но он может просто лежать в блоке).
Быстрый ответ: каждый раз, когда вы ВСТАВЛЯЕТЕ или ПРИСОЕДИНЯЕТЕ данные к серии, если буфер серии заполнен, менеджер памяти перераспределит серию в более крупную. Если вы расширяете серию несколько раз (например, добавляете данные в серию в цикле), если вы не выполняете предварительное выделение, вы можете в конечном итоге потреблять много дополнительной памяти для всех перераспределений и, возможно, в какой-то момент , также вызывая проходы сборщика мусора. Обычно это приводит к значительному замедлению выполнения программы и потреблению большого количества дополнительной памяти. Предварительное выделение буфера серии до размера, достаточного для хранения всех окончательных данных, позволит избежать всех этих проблем с памятью и производительностью.
В случае dups: copy []
вы выделяете минимальный буфер серии (с размером, вероятно, 8 или 16 слотов), поэтому, если все ваши данные не помещаются в этот буфер, ваша программа оплатит (тяжелую) стоимость перераспределения (с). Кроме того, []
— это предварительно выделенная литеральная серия минимального размера, которую вы просто используете в качестве шаблона для создания новой серии, поэтому лучше не тратить память впустую и вместо этого написать: dups: make block! 0
, которая выделит блок! серия минимального размера без потери лишнего блока! ряд.
предварительное выделение буфера необходимо для низкоуровневой функции read-io
если вам нужно, например. доступ к точному коду ошибки при чтении данных можно использовать read-io вместо копирования на открытые порты.
read-io сравним с READ в языках Си. Вы предоставляете read-io предварительно выделенный фиксированный буфер и длину буфера. Если вы попробуете read-io с длиной буфера больше предварительно выделенной, вы делаете это на свой страх и риск.
я только что проверил
>> a: make block! 10000
>> b: copy []
>> delta-time [loop 10000 [append a 1]]
== 0:00:00.004315
>> delta-time [loop 10000 [append b 1]]
== 0:00:00.005795
Разница чуть меньше сотой доли секунды.
Затем я перезапустил rebol и проверил:
>> a: make block! 10000
>> b: copy []
>> delta-time [loop 20000 [append a "test"]]
== 0:00:00.000238
>> delta-time [loop 20000 [append b "test"]]
== 0:00:00.000223
Нет предварительного размещения быстрее, чем предварительное размещение!
0.005795 / 0.004315
увеличивает время выполнения примерно на 34 % без предварительного выделения памяти.
- person DocKimbel; 17.04.2013
Я согласен с Ладиславом в том, что, вероятно, дельта-время ненадежно. Однако я не думаю, что современный ПК нуждается в предварительном распределении, на простой плагин для браузера тратится куча памяти. Я считаю, что сборщика мусора Rebol достаточно для обычного использования. (Возможно, в устройстве Android все еще проблемы со скоростью и памятью)