Страницы: 1
RSS
Power Query.Скорость внутренних вычислений, Довольно медленно обновляется запрос. Можно ли как то улучшить положение?
 
Здравствуйте, уважаемые!
Осваиваю Power Query, опыта в нем - с гулькин этот... как его... нос, во! :)
Вопрос в чем - есть данные в CSV (выгрузка биржевых данных) строк так на 3000. Стоит задача присобачить 2 скользящие средние. Периоды скользящих средних задаются в
таблице параметров (tb_parametrs). Добавляю скользящие средние через подсмотренный прием с использованием индекса, List.Average, List.Range.
НО ЧЕГО ТАК ДОЛГО-ТО?!
На обновление запроса из 3000 строк данных уходит порядка 50-60 секунд. Формулами на листе такой объем при вычислении скользящих средних через СМЕЩ и т.д. делается мгновенно почти. А тут так тупит. Процессор при выполнении запроса грузится максимум до 40%, память до 50%. Подскажите, в чем может быть затык, или это для Power Query нормальная скорость?

Спасибо за внимание.
Текст запроса - под спойлером.
Скрытый текст
Кому решение нужно - тот пример и рисует.
 
Пытливый, приветствую!
Может я и не попал в вопрос (слабо использую PQ), но вот тут…
…Николай Владимирович рассказывает про List.Buffer
Изменено: Jack Famous - 14.09.2021 15:35:17
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Пытливый, текст - это хорошо, Но вот файл-пример бы еще.
Фиговый алгоритм вы используете, надо другой. Тут List.Generate использовать надо. По ссылке под спойлером. И вот еще вариант от Андрей VG.
Изменено: PooHkrd - 14.09.2021 15:53:00
Вот горшок пустой, он предмет простой...
 
Да, конечно. Вот примеры. Положить в C:\1\

Единственное, если не затруднит, можно с подробными пояснениями - а то знаний так мало, что я боюсь не осознать всю красоту предлагаемого решения. Я этот то прием по шагам буквально осваивал, хотя казалось бы... :)

З.Ы. Поправьте, если ошибаюсь, но существенный прирост скорости может дать использование не конкретного столбца стаблицы данных, а предварительно сформированный при помощи List.Bufer перечень значений из этого столбца? А уж потом его использовать в конструкции each try... otherwise?

З.З.Ы. Не поправили пока, но я ошибаюсь. Неправильно понимаю.
я туп, хнык... :(

Файлы удалены - превышение допустимого размера вложения [МОДЕРАТОР]

З.З.З.Ы. Извините. Давно не заходил в правила, почему-то отложилось, что теперь на форуме допускается до 500КБ вложение.
Ужал файлы, перезалил.
Изменено: Пытливый - 15.09.2021 09:07:49
Кому решение нужно - тот пример и рисует.
 
Цитата
Пытливый написал:
Я этот то прием по шагам буквально осваивал, хотя казалось бы...
Этот прием имитирует формулы экселя.
Тем и плох почти во всех случаях, в строки PQ умеет, но скорость всегда поражает.
 
Пытливый, в использованном вами алгоритме схема такая:
А давайте в каждую из строк таблицы на 3к строк сунем еще по такой же таблице, а потом начнем там внутри обращаться к конкретным адресам строк и еще делать всякое непотребное.
Т.е. вы получаете 3к * 3к итого таблу на 9кк строк и пытаетесь ее гнуть по всякому. Вот PQ и начинает задумываться. Это я еще не говорю про "ленивость" вычислений и всю остальную муть.
Вариант с List.Generate работает иначе, он берет столбец в 3к элементов, и в цикле пробегается по нему за один проход, а потом мы "приклеиваем" получившийся столбец к исходной таблице справа. Щас пока занятой. Чуть позже или завтра утром попробую выделить время для решения. А это вам чтоб не скучалось.
Изменено: PooHkrd - 14.09.2021 17:05:58
Вот горшок пустой, он предмет простой...
 
Цитата
PooHkrd написал:
А  это вам  чтоб не скучалось
Таймер взрыва мозга начал отсчет... Тем, кто такое придумывает надо либо памятник, либо гвоздь в голову в детстве... чтоб других не мучали... :|
Кому решение нужно - тот пример и рисует.
 
Цитата
Пытливый написал:
взрыва мозга
А чего там такого? Ну, универсальная функция генерации списков. На VB.NET будет как-то так
Код
Public Delegate Function NonAgrument() As Object
Public Delegate Function SingleArgument(ByVal arg1 As Object) As Object

Module Module1
   'Аналог List.Generate
   Public Function Generate(
         ByVal Initial As NonAgrument,
         ByVal Condition As SingleArgument,
         ByVal NextItem As SingleArgument,
         ByVal Selector As SingleArgument) As ICollection

      Dim curItem As Object = Initial()
      Dim result As New Collection
      Do While DirectCast(Condition(curItem), Boolean)
         result.Add(Selector(curItem))
         curItem = NextItem(curItem)
      Loop
      Return result
   End Function

   Function myInitial() As Object
      Return 5
   End Function

   Function myCondition(ByVal item As Object) As Object
      Return CType(item, Long) < 11
   End Function

   Function myNextItem(ByVal item As Object) As Object
      Return CType(item, Long) + 1
   End Function

   Function mySelector(ByVal item As Object) As Object
      Return item
   End Function
   Sub Main()
      Dim test As Collection = Generate(
         AddressOf myInitial,
         AddressOf myCondition,
         AddressOf myNextItem,
         AddressOf mySelector)
      For Each item As Object In test
         Console.WriteLine(item)
      Next
      Console.ReadKey()
   End Sub
End Module
 
Андрей VG, вы так пишете, как будто я в этом что-то понимаю! :)
Я ж самоучка по VBA для Excel по Уокенбаху, я ж даже в VBA в Outlook буду путаться. :)
Кому решение нужно - тот пример и рисует.
 
PooHkrd, а где я там таблицу пихаю в таблицу? Я ж вычисляю список (плавающий от обрабаываемой позиции), вычисляю его среднее и пихаю значение в новый столбец, где там таблица в таблице?
Не, я подозреваю, что я в силу дремучести неправильно все понимаю, но тогда направьте живительные потоки знания на засушливое поле моего невежества! :)
Кому решение нужно - тот пример и рисует.
 
Цитата
Пытливый написал:
а где я там таблицу пихаю в таблицу?
При расчете нового столбца вы по сути запускаете цикл по расчету для каждой строки таблицы. И там в формуле вы используете конструкцию
List.Range( Индекс[#"<CLOSE>"], [Индекс]-MA_slow_step, MA_slow_step )
Вот то что выделено красным это ссылка на столбец таблицы Индекс из предыдущего шага. т.к. PQ использует "ленивые" вычисления (т.е. все составные элементы он рассчитывает тогда когда видит ссылку на этот элемент, а после расчета он его нигде не хранит и "забывает") то он при виде такой ссылки для каждой строки в вашей формулы производит вычисление всех предыдущих шагов, после этого только забирает список и вытаскивает из него нужный вам кусок. Поэтому такие клины.
Есть вариант ускорить вычисление, это добавить отдельный шаг типа
Код
Список = List.Buffer(Индекс[#"<CLOSE>"])

Об этом писал Jack Famous выше. После чего в формуле использовать именно имя Список. Такая конструкция уже значительно ускорит работу запроса, т.к. список будет принудительно сохранен в памяти и по ссылке будет забираться именно оттуда, а не рассчитываться каждый раз по новой.
Ну а с List.Generate будет еще быстрее, выше я описывал почему.
Вот горшок пустой, он предмет простой...
 
Ага, как я и подозревал, в силу своей дремучести неправильно понял совет по List.Buffer. Попробую, спасибо, Jack Famous.

И все-таки, PooHkrd, можете привести пример использования List.Generate для моего случая? Очень уж охота разобраться, а пока я ну вот реально в голову не могу забрать его концепцию использования. Спасибо.

P.S. Ну, блин! List.Buffer, а не List.Bufer, а я еще такой удивляюсь - чего не работает нифига!  :oops:
P.P.S. Едрит-мадрид, вот теперь я понимаю разницу!!!
Изменено: Пытливый - 15.09.2021 10:27:58
Кому решение нужно - тот пример и рисует.
 
Пытливый, с генератором чуть позжее, это надо чуть глубже погрузиться в ваш алгоритм, пока работа. А по буферу мы вот тут общались очень подробно Максим Зеленский разжевал, а еще ссылку дал на пост от разработчика, в котором тот подробно разложил схему расчета запросов под капотом движка, но там на ангельском.
Вот горшок пустой, он предмет простой...
 
PooHkrd, ага, еще раз спасибо, пошел читать.
Кому решение нужно - тот пример и рисует.
 
Пытливый, В общем попробовал, так даже медленнее получилось. Так что пользуйтесь буфером и вашим алгоритмом, был не прав.
Вот горшок пустой, он предмет простой...
 
PooHkrd, ок, спасибо!
Кому решение нужно - тот пример и рисует.
Страницы: 1
Наверх