List.Generate, накопленная сумма, списки, записи и какие-то метаданные
#АнатомияФункций – List.Generate
Всем привет!
В своё время мы уже разбирали использование List.Generate и считали накопленную сумму.
Стандартный расчёт выглядит так (описание работы смотрим по ссылке):
И тут был задан вопрос – а обязательно ли использовать запись (record) при вычислении?
Ну вообще-то необязательно, давайте примотаем списки:
т.е. вместо записи через вычисления тащим список из двух значений, приходится дважды вычислять счётчик, но в целом это работает.
Однако, пока писал ответ, возникла другая мысль – а давайте примотаем метаданные:
т.е. вместо списка значений запихиваем накопленную сумму в метаданные нашего значения, при этом приходится использовать Value.Metadata и Value.ReplaceMetadata, что делает код несколько громоздким, зато см. промеры по скорости в первом комментарии под постом – это вполне себе шустро.
Поэтому делаем выводы: накопленная сумма – это тот случай, когда НА ЗАПИСЯХ быстрее, а вариант с метаданными, пусть чуть медленнее, зато весьма экзотичен.
Решайте задачи разными путями – это бывает интересно 😉
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций – List.Generate
Всем привет!
В своё время мы уже разбирали использование List.Generate и считали накопленную сумму.
Стандартный расчёт выглядит так (описание работы смотрим по ссылке):
let
lst = List.Buffer({1..250000}),
n=List.Count(lst),
gen = List.Generate(()=>[i=0,s=lst{i}],
(x)=>x[i]<n,
(x)=>[i=x[i]+1,s=x[s]+lst{i}],
(x)=>x[s])
in
gen
И тут был задан вопрос – а обязательно ли использовать запись (record) при вычислении?
Ну вообще-то необязательно, давайте примотаем списки:
let
lst = List.Buffer({1..250000}),
n=List.Count(lst),
gen = List.Generate(()=>{0,lst{0}},
(x)=>x{0}<n,
(x)=>{x{0}+1,x{1}+lst{x{0}+1}},
(x)=>x{1})
in
gen
т.е. вместо записи через вычисления тащим список из двух значений, приходится дважды вычислять счётчик, но в целом это работает.
Однако, пока писал ответ, возникла другая мысль – а давайте примотаем метаданные:
let
lst = List.Buffer({1..250000}),
n = List.Count(lst),
gen = List.Generate(()=>0 meta [s=lst{0}],
(x)=>x<n,
(x)=>Value.ReplaceMetadata(x+1,[s=Value.Metadata(x)[s]+lst{x+1}]),
(x)=>Value.Metadata(x)[s])
in
gen
т.е. вместо списка значений запихиваем накопленную сумму в метаданные нашего значения, при этом приходится использовать Value.Metadata и Value.ReplaceMetadata, что делает код несколько громоздким, зато см. промеры по скорости в первом комментарии под постом – это вполне себе шустро.
Поэтому делаем выводы: накопленная сумма – это тот случай, когда НА ЗАПИСЯХ быстрее, а вариант с метаданными, пусть чуть медленнее, зато весьма экзотичен.
Решайте задачи разными путями – это бывает интересно 😉
Надеюсь, было полезно.
Всех благ!
@buchlotnik