Предыдущие посты серии:
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
