Поиск  Пользователи  Правила 
Закрыть
Логин:
Пароль:
Забыли свой пароль?
Регистрация
Войти
 
Страницы: 1
RSS
Power Query Table.Buffer List.Buffer, Хочется понимания,как зависит производительность
 
Источник https://blog.crossjoin.co.uk/2015/05/05/improving-power-query-calculation-performance-with-list-buff... но понимания зачем нет
Например в https://msdn.microsoft.com/query-bi/m/table-buffer пишет
Буферизирует таблицу в памяти, изолируя ее от внешних изменений во время оценки
Это как?
Изменено: volond75 - 5 Апр 2018 11:20:19 (Не корректно поставил запрос)
"Правильно заданный вопрос,половина ответа!"
 
Доброго дня, ранее обсуждалось вот в таком ключе. Просмотрите, если что останется не ясным - спрашивайте дальше.
А если вкратце - эти функции заставляют PQ не строить цепочку преобразований - оптимизаций в интерпретаторе, а принудительно рассчитать выражение и результат закинуть в память присвоив этому результату имя шага на котором вызывалась функция, если к этому имени будете обращаться в дальнейшем, то результат будет не рассчитывать вновь, а сразу браться готовый из памяти.
Тут главное не переборщить с размерами массивов, которые планируете буфферизовать, а то можно получить обратный эффект.
 
Тоесть на больших таблицах при ограничениях на память ОЗУ могут быть проблемы?
"Правильно заданный вопрос,половина ответа!"
 
Обратите внимание на процессы в диспетчере задач во время выполнения скриптов. Есть там такие Microsoft Mashup Evaluation Container. Все вычисления PQ передает в них. Вот у них есть ограничения один процесс максимум 256 Мб, и одновременно может работать не более 4 процессов. Соответственно если вы напихаете в них данных больше чем на 1 Гиг, то все что сверху PQ начнет кэшировать на жесткий диск. И хорошо если это у вас SSD. А если HD? Со всеми вытекающими.
Как я использую функцию: Например нужно выполнить запрос, который на выходе дает список значений.
Код
let
    Today = DateTime.Date(DateTime.LocalNow()),

    Source2 = 
    Table.FromList(
        List.Dates(
            Today + Duration.From(1), 
            55, 
            Duration.From(1)), 
        Splitter.SplitByNothing() ),
    AddColMonths = Table.AddColumn(Source2, "Month", each Date.ToText([Column1], "yyyy/MM"), type text),
    DaysToForecast = List.Buffer( Table.Group(AddColMonths, {"Month"}, {{"Diff", each Number.From(List.Max([Column1]) - List.Min([Column1]) ) + 1, type date}})[Diff] )
in
    DaysToForecast

В дальнейшем эти значения будут применены для расчетов в примерно 300 000 ячеек, и если бы в последнем шаге я не применил List.Buffer, то каждый раз при обращении к значениям этого списка из-за ленивых вычислений весь код будет выполняться с самого начала, это миллисекунды, но если их умножить на 300 000, то оно вырастает в минуты. Применив же функцию, запрос вычисляется один раз, закидывает список в память и в остальные разы читает значения уже из памяти - ПРОФИТ!
Вроде ничего не соврал. На моем скрипте без буфера запрос вычисляется минут 5 с буфером 2-2,5 минуты
Изменено: PooHkrd - 5 Апр 2018 11:43:53
 
На последнем шаге В буфер НО 1. таблица остается в памяти в рамках расчета только одного запроса? или DaysToForecast в другом запросе -это уже обращение к буферу?
Изменено: volond75 - 5 Апр 2018 13:35:28
"Правильно заданный вопрос,половина ответа!"
 
Если данный код это отдельный запрос, то его финальный результат помещается в память и к нему можно обращаться по имени запроса из остальных. Если этот код будет частью запроса, и при этом шаг DaysToForecast не будет результатом его вывода, то обращаться к результату можно по имени шага и только в рамках этого запроса.
Изменено: PooHkrd - 5 Апр 2018 12:23:17
 
Цитата
PooHkrd написал:
Обратите внимание на процессы в диспетчере задач во время выполнения скриптов. Есть там такие Microsoft Mashup Evaluation Container. Все вычисления PQ передает в них. Вот у них есть ограничения один процесс максимум 256 Мб, и одновременно может работать не более 4 процессов. Соответственно если вы напихаете в них данных больше чем на 1 Гиг, то все что сверху PQ начнет кэшировать на жесткий диск.
1.List.Buffer или Table.Buffer освобождает один из Microsoft Mashup Evaluation Container?
2.Microsoft Mashup Evaluation Container это по сути соединение с кешированым файлом?
3.Как то можно обнулить буфер как в vba  tablebufer=Table.Buffer (table)  set  tablebufer=nothing
Изменено: volond75 - 5 Апр 2018 13:43:48
"Правильно заданный вопрос,половина ответа!"
 
1. Не понял вопрос
2. Этот процесс производит все вычисления, которые вы генерите вашим запросом
3. Как только запрос завершил работу память должна обнуляться автоматически. Способ принудительно в процессе работы запроса освобождать память мне не известен.
 
Цитата
PooHkrd написал:
Не понял вопрос
Применение в запросе List.Buffer или Table.Buffer освобождает один из Microsoft Mashup Evaluation Container? Просто тоже не понятно почему именно 4 шт Microsoft Mashup Evaluation Container  
"Правильно заданный вопрос,половина ответа!"
 
Нет, наоборот, загружает. Т.е. память выделяется в рамках той, которую забирают себе эти контейнеры. Про 4 штуки не знаю - это из моего личного опыта, какой бы супер запрос я не запускал, больше 4 штук в списке не наблюдал, хотя в наглоязычных интернетах видел упоминания и об 6 штуках. Есть подозрение что количество контейнеров может быть ограничено количеством потоков в процессоре. На моем ноутбуке их 4.
Страницы: 1
Читают тему (гостей: 1)
Наверх