Сортировка в Power Query — зло. Часть 2.Предыдущие посты серии:
1. Документация по промптам.
2. Выбор нейронок.
3. Подготовка к разработке.
4. Оптимизация кода.
5. Если код не "летает".
6. Минимизируем вычисления.
7. Фатальный пример вычислений.
8. Порядок обработки данных.
9. Смерть производительности. Часть 1.
Продолжим список альтернатив сортировке.
7️⃣ Агрегатные функции — сложность
O(n).Эти функции выполняют один проход по данным для вычисления результата.
⚫️ List.Max — поиск максимального значения в списке.
Сложность:
O(n). Применение: вместо тяжелой сортировки всей таблицы по убыванию и взятия первого элемента со сложностью
O(n log n).⚫️ List.Min — поиск минимального значения в списке.
Сложность:
O(n).Применение: Вместо List.Sort + List.First — сортировки по возрастанию и взятия первого элемента.
⚫️ List.Sum — сумма элементов списка.
Сложность:
O(n).Применение: Для агрегации без предварительной сортировки.
⚫️ List.Average — среднее значение элементов.
Сложность:
O(n).Применение: Расчет среднего без сортировки.
⚫️ List.Count — подсчет элементов.
Сложность:
O(1) или
O(n) в зависимости от реализации.
Применение: Быстрый подсчет элементов без материализации.
⚫️ Table.RowCount — количество строк в таблице.
Сложность:
O(1) при наличии метаданных.
Применение: Быстрая проверка размера данных.
✅ Правильный паттерн:
Group +
Aggregate❌ Неправильный паттерн:
Group +
Sort внутри каждой группы
————
8️⃣ Функции фильтрации и поиска —
O(n).Фильтрация почти всегда дешевле сортировки и должна выполняться раньше.
⚫️ List.Select — фильтрация списка по условию.
Сложность:
O(n).Применение: Отбор элементов без сортировки.
⚫️ Table.SelectRows — фильтрация строк таблицы.
Сложность:
O(n).Применение: Основной метод фильтрации в Power Query.
⚫️ List.PositionOf — поиск позиции элемента.
Сложность:
O(n).Применение: Линейный поиск в несортированном списке.
⚫️ List.Contains — проверка наличия элемента.
Сложность:
O(n).Применение: Быстрая проверка существования.
⚫️ Table.Distinct — удаление дубликатов.
Сложность:
O(n) с использованием хеш-таблицы.
Применение: Дедупликация без сортировки.
⚫️ List.Distinct — уникальные элементы списка.
Сложность:
O(n).Применение: Получение уникальных значений.
⚫️ Record.Field — сложность
O(1).Применение: Самый быстрый способ поиска (
Lookup) по ключу.
————
9️⃣ Индексация и lookup —
O(1) или
O(n).
⚫️ Table.AddIndexColumn — добавление индекса строки.
Сложность:
O(n) для создания,
O(1) для доступа.
Применение: Быстрый доступ по позиции после создания индекса
⚫️ Table.Buffer — кеширование таблицы.
Сложность:
O(n) для создания буфера.
Применение: Предотвращение повторных вычислений.
⚫️
Record lookup (обращение к полю записи) — прямой доступ.
Сложность:
O(1).Применение: Самый быстрый способ
lookup в M.
⚫️ List.Buffer — кеширование списка в памяти.
Сложность:
O(n) для создания,
O(1) для последующих обращений.
Применение: Оптимизация повторных операций.
List.Buffer +
lookup — сложность
O(n) на построение, дальше —
O(1).Record и
Join почти всегда лучше, чем сортировка + поиск.
————
1️⃣0️⃣ Объединение —
O(n + m).⚫️ Table.NestedJoin — вложенное соединение.
Сложность:
✅ Хорошо:
O(n + m) — с правильными ключами.
❌ Плохо:
O(n × m) — без оптимизации.
Применение:
Join с сохранением вложенной структуры. При использовании
Hash Join это намного быстрее, чем вложенные циклы.
⚠️ Недостаток: Table.NestedJoin медленее, чем Table.Join, т.к. первая присоединяет и разворачивает вложенные таблицы в каждой строке, а вторая — всю таблицу целиком.
⚫️ Table.Join — соединение таблиц с хешированием.
Сложность:
O(n + m) при использовании
hash join.
Применение: Объединение данных без сортировки.
⚠️ Неудобство: названия столбцов в таблице 2 не должны повторять названия столбцов из таблицы 1.
————
1️⃣1️⃣ Специализированные функции.
⚫️ List.BinarySearch — бинарный поиск в отсортированном списке.
Сложность:
O(log n).Применение: Эффективный поиск, но требует предварительной сортировки.
В следующем посте — плохие и хорошие примеры с анализом сложности вычислений.
via
@ppc_bigbrain