Порождающий запрос
Файлы
ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.
| Наименование | Скачано | Купить файл | По подписке PRO |
|---|---|---|---|
|
Текст запроса
.txt 1,06Kb
74
|
74 | 2 500 руб. Купить | 1 SM Скачать |
|
Текст запроса для определения частоты символов заданного текста
.txt 1,36Kb
29
|
29 | 2 500 руб. Купить | 1 SM Скачать |
|
Отчет разбора текста на слова запросом
.erf 6,96Kb
33
|
33 | 2 500 руб. Купить | 1 SM Скачать |
|
Текст запроса квадратного корня
.txt 0,95Kb
20
|
20 | 2 500 руб. Купить | 1 SM Скачать |
Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний
Оформите подписку на компанию для решения рабочих задач
Оформить подписку и скачать решение со скидкойВы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.
Суть решения в том, что в пакетном запросе сначала заводится таблица с двумя строками, затем она соединяется сама с собой и число строк удваивается. Так повторяется до достижения таблицей заданного размера. Этот способ обеспечивает использование минимума соединений, от числа которых, в основном, зависит время выполнения запроса.
Для примера приведен запрос, формирующий таблицу из чуть более миллиона строк.
ВЫБРАТЬ 0 КАК Х
ПОМЕСТИТЬ Регистр1
ОБЪЕДИНИТЬ
ВЫБРАТЬ 1
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Младшие.Х + 2 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр2
ИЗ Регистр1 КАК Младшие, Регистр1 КАК Старшие
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Младшие.Х + 4 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр4
ИЗ Регистр2 КАК Младшие, Регистр2 КАК Старшие
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Младшие.Х + 16 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр8
ИЗ Регистр4 КАК Младшие, Регистр4 КАК Старшие
;
///////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Младшие.Х + 256 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр16
ИЗ Регистр8 КАК Младшие, Регистр8 КАК Старшие
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Младшие.Х + 65536 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр20
ИЗ Регистр16 КАК Младшие, Регистр4 КАК Старшие
С его помощью можно сформировать таблицу значений в миллион строк примерно за 2 секунды, тогда как при использовании обычного метода последовательного добавления строк на это уйдет в два раза больше времени.
Для примера того, как можно использовать искусственные таблицы в запросах, приводится запрос, определяющий частоту символов в некотором тексте.
Текст и его длина передаются в запрос как параметры. Для примера считаем, что длина текста ограничена миллионом символов. Вот текст концовки этого запроса.
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ ПОДСТРОКА(&Текст, Х, 1) Символ, КОЛИЧЕСТВО(Х) КАК Частота
ИЗ Регистр20
ГДЕ Х МЕЖДУ 1 И &ДлинаТекста
СГРУППИРОВАТЬ ПО ПОДСТРОКА(&Текст, Х, 1)
Его начало такое же как на предыдущем рисунке. Интересно то, что этот метод работает быстрее, чем обработка в оперативной памяти. И сразу дает табличный результат! Например, первый мегабайт романа "Война и мир" обрабатывается в памяти 8,2 сек, а запросом - 4 секунды!
Очевидно, что запрос совсем простой. Проявив некоторую изобретательность, можно построить запрос разбора текста на слова и запросы для решения других задач обработки текста. Аналогично можно строить таблицы вхождений одно, двух, трех и т.п. символов в наименования, артикулы и пр. для ускорения подбора (вместо методов с использованием "подобно").
Определение частоты слов запросом оказалось совсем не тривиальной задачей. Вот решение:
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Младшие.Х + 256 * 256 * Средние.Х + 256 * 256 * 2 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр21
ИЗ Регистр16 КАК Младшие, Регистр4 КАК Средние, Регистр1 КАК Старшие
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Х КАК У
ПОМЕСТИТЬ Разделители
ИЗ Регистр21
ГДЕ (НЕ ПОДСТРОКА(&Текст, Х, 1) ПОДОБНО "[а-я]") И Х МЕЖДУ 1 И &ДлинаТекста
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ Х, ВЫБОР КОГДА Х = 0 ТОГДА ИСТИНА КОНЕЦ КАК Нулевой, ВЫБОР КОГДА Х > 0 ТОГДА Х КОНЕЦ КАК Длина
ПОМЕСТИТЬ Интервалы
ИЗ Регистр4
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ У - Х КАК Начало, МИНИМУМ(Длина) КАК Длина
ПОМЕСТИТЬ УказателиСлов
ИЗ Разделители, Интервалы
СГРУППИРОВАТЬ ПО У - Х
ИМЕЮЩИЕ МАКСИМУМ(Нулевой) = ИСТИНА И МИНИМУМ(Длина) > 1
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ ПОДСТРОКА(ПОДСТРОКА(&Текст, Начало + 1, Длина - 1), 1, 15) КАК Слово, КОЛИЧЕСТВО(Начало) КАК Частота
ИЗ УказателиСлов
СГРУППИРОВАТЬ ПО ПОДСТРОКА(ПОДСТРОКА(&Текст, Начало + 1, Длина - 1), 1, 15)
К статье прилагается файл отчета, содержащий этот запрос. С его помощью в тексте первой части "Войны и мира" была определена частота слов за 24 секунды! А это примерно 1,5 миллиона символов! Правда, если использовать "кодинг", на чистом 1С можно решить ту же задачу примерно в два раза быстрее.
В качестве неочевидного применения предложенного запроса приводится пример расчета в запросе квадратного корня от числа в диапазоне 0 - 1 048 576. Вернее, целой части этого корня.
////////// создается таблица с числами от 0 до 1024 ////////////////////////////
ВЫБРАТЬ 0 КАК Х ПОМЕСТИТЬ Регистр1 ОБЪЕДИНИТЬ ВЫБРАТЬ 1
;
ВЫБРАТЬ Младшие.Х + 2 * Старшие.Х КАК Х ПОМЕСТИТЬ Регистр2
ИЗ Регистр1 КАК Младшие, Регистр1 КАК Старшие
;
ВЫБРАТЬ Младшие.Х + 4 * Старшие.Х КАК Х ПОМЕСТИТЬ Регистр4
ИЗ Регистр2 КАК Младшие, Регистр2 КАК Старшие
;
ВЫБРАТЬ Младшие.Х + 16 * Старшие.Х КАК Х ПОМЕСТИТЬ Регистр8
ИЗ Регистр4 КАК Младшие, Регистр4 КАК Старшие
;
ВЫБРАТЬ Младшие.Х + 256 * Старшие.Х КАК Х ПОМЕСТИТЬ Регистр10
ИЗ Регистр8 КАК Младшие, Регистр2 КАК Старшие
;
////////// для проверки создается таблица с различными значениями аргумента ////
ВЫБРАТЬ 123456 КАК У ПОМЕСТИТЬ Аргументы
ОБЪЕДИНИТЬ ВЫБРАТЬ 555555
ОБЪЕДИНИТЬ ВЫБРАТЬ 987654
;
////////// формируется таблица, содержащая аргумент и значение функции /////////
ВЫБРАТЬ У, МАКСИМУМ(Х) КАК Квадратный_корень_Х
ИЗ Аргументы ЛЕВОЕ СОЕДИНЕНИЕ Регистр10 ПО (Х * Х < У)
СГРУППИРОВАТЬ ПО У
Аналогичным или похожим путем можно рассчитать и другие обратные функции.
Похожим приемом в запросе можно получить "таблицу хаоса" - таблицу, которая содержит случайные числа. Например, следующая функция возвращает таблицу с заданным числом строк, содержащую случайные числа, равномерно распределенные в диапазоне 0 - 1.
function ChaosTable(N, Name = "СлучайноеЧисло") export
g = new RandomNumberGenerator();
q = new Query("select &r1 as r into t1 union select &r2;
| select &k * a.r + b.r - cast((&k * a.r + b.r) / &M - 0.5 as number(10,0)) * &M as r into t2 from t1 as a, t1 as b;
| select &k * a.r + b.r - cast((&k * a.r + b.r) / &M - 0.5 as number(10,0)) * &M as r into t4 from t2 as a, t2 as b;
| select &k * a.r + b.r - cast((&k * a.r + b.r) / &M - 0.5 as number(10,0)) * &M as r into t8 from t4 as a, t4 as b;
| select &k * a.r + b.r - cast((&k * a.r + b.r) / &M - 0.5 as number(10,0)) * &M as r into t16 from t8 as a, t8 as b;
| select top " + Format(N, "NG=") + "
| (&k * a.r + b.r) / &M - cast((&k * a.r + b.r) / &M - 0.5 as number(10,0)) as " + Name + " from t16 as a, t4 as b");
q.SetParameter("r1", g.RandomNumber()); q.SetParameter("r2", g.RandomNumber());
q.SetParameter("k", 1664525); q.SetParameter("M", 4294967295);
return q.Execute().Unload()
endfunction
Такая функция работает примерно в полтора раза быстрее, чем генерация случайных чисел для заполнения таблицы в цикле, а результат может использоваться прямо в запросе. В основе построения запроса лежит линейный конгруэнтный метод получения последовательности псевдослучайных чисел. Сложное выражение внутри запроса является ничем иным как нахождением остатка от деления на &M. К сожаления, непосредственно функции деления по заданному модулю в языке запросов нет.
Конечно, для использования в ответственных применениях потребуется проверка результата тестами NIST. Также было бы интересно исследовать использование для решения той же задачи метода Блюма-Блюма-Шуба. Запись запроса при этом будет еще короче.
Для удобства применения предложенного подхода на практике предлагается функция, которая формирует ТЕКСТ ЗАПРОСА или фрагмент пакетного запроса, выполнение которого приводит к получению временной таблицы, содержащей натуральный ряд чисел заданного размера. Вот текст этой функции
function ProtoText(N, M = 1000000000) export
return ?(N > 2
, ProtoText(M - Int(M - Sqrt(N)))
+ strreplace(strreplace(";select top #2 a.X * #1 + b.X X into r#2 from r#1 a, r#1 b; drop r#1", "#2", format(N, "NG=")), "#1", format(M - Int(M - Sqrt(N)), "NG="))
, "select 0 X into r2 union select 1")
endfunction
Функция рекурсивная, параметр M - служебный (используется для сокращения записи функции). Результирующая временная таблица имеет имя r{ЗаданныйРазмер}.
Вступайте в нашу телеграмм-группу Инфостарт
См. также
Инструментарий разработчика Роли и права Запросы СКД Разработчик Руководитель проекта 1С:Предприятие 8 Платные (руб)
Инструменты для разработчиков 1С 8.3 и 8.5: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.
16500 руб.
02.09.2020 285460 1606 423
Инструментарий разработчика Запросы Разработчик 1С 8.3 1С:Бухгалтерия 3.0 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)
Структура запроса. Обработка визуально показывает, из какого количества подзапросов состоит запрос.
2 стартмани
06.07.2026 4920 65 XSlava 20
Запросы Разработчик 1С 8.3 Россия Бесплатно (free)
Визуальный «Конструктор запроса» 1С, встроенный прямо в VS Code, — аналог конструктора из Конфигуратора и EDT, но без запуска платформы. Расширение читает конфигурацию, выгруженную в файлы, позволяет собрать запрос мышью и генерирует корректный текст на языке запросов 1С (SDBL). Открывает уже существующий текст запроса из кода для правки и — что особенно ценно — сохраняет комментарии при цикле «открыть - править - сохранить». Подходит тем, кто пишет код 1С в VS Code, держит под рукой множество проектов и не хочет ради одного запроса запускать тяжёлый Конфигуратор или EDT.
26.06.2026 10641 Alex_YAM 7
Нейросети Инструментарий разработчика Запросы Разработчик 1С:Предприятие 8 Абонемент ($m)
Консоль запросов 1.0: добавлен ИИ-помощник (запрос в DeepSeek), который помогает быстрее получать каркас Запроса 1С Сформулируйте простое описание; нажмите кнопку – получите результат прямо в консоли. Где дальше его можно дорабатывать и тестировать. 28.5.2026 Добавил "Консоль запросов 2.0" (запрос в DeepSeek + Claude) 4.10.2026 Обновил "Консоль запросов 2.0"
3 стартмани
20.05.2026 9546 46 German4739 72
WEB-интеграция Запросы Разработчик 1С 8.3 Абонемент ($m)
Post1C - это внешняя обработка, которая превращает 1С в полноценный инструмент для тестирования REST API. Всё управление сосредоточено в одном окне: настройка запроса, выполнение, просмотр ответа и генерация кода - без переключения между формами. Аналог Postman, но работающий в привычной среде 1С.
1 стартмани
02.04.2026 4630 105 priem_nv 27
Запросы Механизмы типовых конфигураций Разработчик 1С:Предприятие 8 1С:Управление торговлей 11 Россия Бесплатно (free)
Предлагается обзор работы с объектной моделью запроса по схемам запросов типовым функционалом УТ 11.5.
09.10.2025 13378 aximo 18
Инструментарий разработчика Запросы Разработчик 1С:Предприятие 8 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)
QueryConsole1C — расширение, включающее консоль запросов с поддержкой исполняемых представлений — аналогов виртуальных таблиц, основанных на методах программного интерфейса ЗУП. Оно позволяет выполнять запросы с учётом встроенной бизнес-логики, отлаживать алгоритмы получения данных и автоматически генерировать код на встроенном языке 1С.
1 стартмани
16.05.2025 13641 168 zup_dev 32
Инструментарий разработчика Запросы Разработчик 1С:Предприятие 8 1С:ERP Управление предприятием 2 Абонемент ($m)
В данной публикации рассказывается о решении, которое позволяет находить сразу все ошибки в тексте запроса за раз, а не только самую первую.
2 стартмани
05.03.2025 7705 25 XilDen 12
3000чертей!
повторил запрос, 1с-серв всю память сьел и подавился, а предприятие зависло... предупреждать надо!! :(((
кстати, для создания ТЗ определённого размера можно использовать COMSafeArray
Важен принцип, а конкретный запрос приведен для примера и оценки скорости (замеры делались на ноутбуке в файловом варианте базы).
По аналогии можно формировать и меньшие таблицы.
Если их размер не равен степеням двойки, используем условие ГДЕ X < &ЗаданныйРазмер.
За напоминание о COMSafeArray спасибо!
(4) Запрос из я видел,
хотя за основу брал свое же решение из (внешнего сходства немного, но общая "математика").
Отличие от я вижу в том, что:
1) оно нацелено не только на даты (кроме того, что уже сказано, например, на основе этого запроса можно подбором находить обратные функции, не вычисляемые в запросе, типа квадратного корня и прочих);
2) оптимизировано по времени выполнения за счет соединения таблицы с собой (различные варианты сравнивались).
(5) Цикл из миллиона повторений сразу сделает этот прием неконкурентоспособным, а вот если все время удваивать подстроку - может и получиться...
Запрос.Текст = "ВЫБРАТЬ
| 0 КАК Бит
|ПОМЕСТИТЬ Регистр
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| 1
|;
|
|//////////////////////////////////////////////////////////// ////////////////////
|ВЫБРАТЬ
| Н10.Бит + 2 * Н9.Бит + 4 * Н8.Бит + 8 * Н7.Бит + 16 * Н6.Бит + 32 * Н5.Бит + 64 * Н4.Бит + 128 * Н3.Бит + 256 * Н2.Бит + 512 * Н1.Бит + 1024 * Н0.Бит + 2048 * Н11.Бит КАК Сумма
|ИЗ
| Регистр КАК Н11,
| Регистр КАК Н10,
| Регистр КАК Н9,
| Регистр КАК Н8,
| Регистр КАК Н7,
| Регистр КАК Н6,
| Регистр КАК Н5,
| Регистр КАК Н4,
| Регистр КАК Н3,
| Регистр КАК Н2,
| Регистр КАК Н1,
| Регистр КАК Н0" ПоказатьН10.Бит + 2 *(Н9.Бит + 2 * (Н8.Бит + 2 * (Н7.Бит + 2 * (Н6.Бит + 2 * (Н5.Бит + 2 * (Н4.Бит + 2 * (Н3.Бит + 2 * ( Н2.Бит + 2 * (Н1.Бит + 2 * (Н0.Бит + 2 * Н11.Бит)))))))))) Получил следующие результаты.
Запросы типа (7), (17), (19) проигрывают (0) в файловом варианте как на 8.1, так и на 8.2.
А вот в SQL варианте они работают быстрее как на 8.1, так и на 8.2. MS SQL 2005 Standart.
Возможно, что на других SQL серверах будут другие результаты.
Запрос, который участвовал в тестировании:
выбрать 0 как х поместить х0 объединить все выбрать 1
объединить все выбрать 2 объединить все выбрать 3 объединить все выбрать 4
объединить все выбрать 5 объединить все выбрать 6 объединить все выбрать 7
объединить все выбрать 8 объединить все выбрать 9
;
выбрать х1.х + х2.х * 10 + х3.х * 100 + х4.х * 1000 + х5.х * 10000 + х6.х * 100000 как х
из х0 как х1, х0 как х2, х0 как х3, х0 как х4, х0 как х5, х0 как х6
Потом, возможно, стоит посмотреть:
0) результаты для (7) и (19), то есть с использованием основания 2;
1) диапазоны до 65536 и более миллиона;
2) вариант с (0), когда начальная таблица - это Регистр4 (выбрать 0 - 15 поместить регистр4).
Это для того, чтобы понять, что влияет больше: число соединений (у (0) и (38) оно одинаково! и, думаю, это главное) или время трансляции запроса в SQL или необходимость фиксации временных таблиц.
Тогда и можно будет сделать выводы о сравнительной применимости (0) и (38) как подходов к формированию искусственных таблиц.
Также уточню гипотезу из (40): Кажется, что подход (38) выигрывает у подхода (0) только в узком диапазоне условий, когда число соединений в запросах получается одинаковым. Под подходами я имел ввиду формирование искусственной таблицы любого заданного размера "взрывным" способом "порождающего запроса" (0), либо линейно-нарастающим числом соединений как в (38).
(14) Видимо, Вы что-то пропустили. Речь как раз идет о
ВЫБРАТЬ
0 КАК Цифра
ПОМЕСТИТЬ ВсеЦифры
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
1
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
2
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
3
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
4
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
5
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
6
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
7
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
8
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
9
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(&ДатаНач, ДЕНЬ, ВсеЦифры4.Цифра * 1000 + ВсеЦифры3.Цифра * 100 + ВсеЦифры2.Цифра * 10 + ВсеЦифры1.Цифра * 1) КАК ДатаДень
ПОМЕСТИТЬ ВсеДни
ИЗ
ВсеЦифры КАК ВсеЦифры1
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВсеЦифры КАК ВсеЦифры2
ПО (ВсеЦифры2.Цифра * 10 + ВсеЦифры1.Цифра * 1 <= РАЗНОСТЬДАТ(&ДатаНач, КОНЕЦПЕРИОДА(&ДатаКон, ДЕНЬ), ДЕНЬ))
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВсеЦифры КАК ВсеЦифры3
ПО (ВсеЦифры3.Цифра * 100 + ВсеЦифры2.Цифра * 10 + ВсеЦифры1.Цифра * 1 <= РАЗНОСТЬДАТ(&ДатаНач, КОНЕЦПЕРИОДА(&ДатаКон, ДЕНЬ), ДЕНЬ))
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВсеЦифры КАК ВсеЦифры4
ПО (ВсеЦифры4.Цифра * 1000 + ВсеЦифры3.Цифра * 100 + ВсеЦифры2.Цифра * 10 + ВсеЦифры1.Цифра * 1 <= РАЗНОСТЬДАТ(&ДатаНач, КОНЕЦПЕРИОДА(&ДатаКон, ДЕНЬ), ДЕНЬ)) Показать"Первая свежесть" идеи (0) в том, чтобы минимизировать число соединений на всех этапах получения искусственной таблицы любого заданного размера и, таким образом, ускорить ее построение. Для этого обеспечивается квадратичный рост размера получаемой таблицы 2 - 4 - 16 - 256 - 65536 - ... На каждом этапе размер возводится в квадрат за одно соединение. Это похожий, но другой, более быстрый принцип (проверял, сравнивал)!
Во-вторых, я предлагаю использовать получаемые таблицы не только для генерации дат в заданном диапазоне, но и для быстрого (проверено!) формирования больших таблиц значений, массивов, списков; для вычисления обратных функций, которых нет в языке запросов; для решения других задач, примеры которых я еще приведу. То есть "вторая свежесть идеи" заключается в обобщении подхода с использованием искусственно-порожденных таблиц, в использовании его для решения других задач.
ВЫБРАТЬ
0 КАК б
ПОМЕСТИТЬ Т
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
1
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
Т0.б + 2 * Т1.б + 4 * Т2.б + 8 * Т3.б + 16 * Т4.б + 32 * Т5.б + 64 * Т6.б + 128 * Т7.б КАК Числа
ИЗ
Т КАК Т0,
Т КАК Т1,
Т КАК Т2,
Т КАК Т3,
Т КАК Т4,
Т КАК Т5,
Т КАК Т6,
Т КАК Т7
УПОРЯДОЧИТЬ ПО
Числа Показать)
В Вашем варианте для получения таблицы из миллиона записей потребуется 19 соединений (число волшебно совпадает с номером Вашего поста), а в моем - 5! 19 и 5 - есть разница? То есть это не просто разная запись, это другой принцип. И, как вижу, все же не очевидный, поскольку столько людей не увидели разницы.
Кстати, в моем варианте (19) используется запись, не требующая знания ряда степеней двойки:
Т0.б + 2 * (Т1.б + 2 * (Т2.б + 2 * (Т3.б + 2 * (Т4.б + 2 * (Т5.б + 2 * (Т6.б + 2 * Т7.б)))))).
Извините, что вынужден повторятся. Вижу, что предыдущие комментарии не читаются.
"Например, первый мегабайт романа "Война и мир" обрабатывается в памяти 8,2 сек, а запросом - 4 секунды!"©
Сергей.
И это не "запрос" молодец, а интерпретатор/компилятор 1С-а бяка. ;-)
Проверил алгоритм в памяти на "1С 7.7".
Если исходные данные в строке - 1249 сек.
Если данные в массиве - 2 сек.
Ну, а перегон из строки в массив занял 1215 сек.
Любопытно, что строка в 100000 символов обрабатывается за 12 сек.
А на С++ алгоритм выполняется - 0,00253 сек.
Правда, меня удивляют приведенные Вами данные. Разбор строки (определение частот) из миллиона символов в оперативной памяти занимает в 8-ке 8,2 секунды (использовал соответствия, запись в одну строку, отключенный отладчик). Неужели 7-ка настолько медленнее? Как-то не верится.
"Неужели 7-ка настолько медленнее? Как-то не верится."(с)
Сергей.
Я тщательно проверял свой текст алгоритма. ;-)
Думаю, время со строкой в 1000000 - это, типа, глюк.
Скорости для строк:
1 000 000 байт - 1249 сек.
100 000 байт - 12 сек.
10 000 байт - 0.157 сек.
1 000 байт - 0.005 сек.
И, вообще, в семерке много подобных "странностей"... :-)
Сергей.
Я напоминаю себе, возней с "семеркой", персонажа:
"Неуловимый Джо — персонаж известного анекдота; обозначает человека или явление, всем известного, но при этом никому не нужного."(с)
Я выяснил. :-)
В "семерке" время выполнения функции Сред(Строка,Позиция,1) линейно зависит от длины исходной строки (первого аргумента). Т.е. эта функция, как бы принимает не адрес строки, а - значение. Блеск... :-) Интересно, а как в "восьмерке" работает такая функция?
Цикл Для ё = 1 По 1048576 Цикл ж = Сред(Текст, ё, 1); Частота[ж] = ?(Частота[ж] = Неопределено, 0, Частота[ж] + 1) КонецЦиклавыполняется 8,2 секунды, а в нем есть еще чтение и запись соответствия.
Про трудности работы с длинными строками в 77 говорилось в одной из здешних публикаций по оптимизации кода в 77. Там предлагалось разбивать строки перед обработкой.
Сергей.
Рекомендации, типа, разбить строки - интересно. :-)
А разбивать строки - функцией Сред(), как это у меня сделано, например, в массив? ;-)
Времена см. в (25) сообщении. Суммарное время выполнения останется прежним. Нет - это не выход. Печально, еще и то, что если написать подобные функции на ВК, то очень большие накладные расходы на вызов методов. Например, метод Х=Lib.DeleteStr("*",1,1) для 100000 вызовов выполняется 160 секунд. А этот метод, всего, что и делает - из строки в один байт удаляет первый символ и возвращает строку нулевой длины. Еще смешней. Время просмотра таблицы в 2700000 циклом - 30 секунд. Но, если в этом цикле выполнять присвоение полей таблицы в рабочие переменные (15 штук, средняя длина поля - 10 байт), то время становится - 140 секунд. А ведь все поля, после чтения записи, уже лежат в оперативной памяти. Вот такая жесть в "семерке"... :-( Я давно пишу "боевые" куски алгоритмов на С++ с минимальным количеством вызовов методов ВК. Т.е. "максимально-целиком" загоняю алгоритм в С++.
Вот... (с)
Я пробовал "разукрашивать" тексты, но у меня потом форматирование разъезжается, решил, что рисунки проще.
RandomNumber(), как известно, может вернуть 0. и вот если так случится, что и в r1, и в r2 придут нули - тогда ой. конструкция &N-cast(&N/&M-0.5 as number(10,0))*&M даст при N = 0 не N % M, а -M
чтобы не городить case внутри запроса, думаю, проще "поднять" нижнюю границу через вызов RandomNumber(1)
ВЫБРАТЬ Х КАК У
ПОМЕСТИТЬ Разделители
ИЗ Регистр21
ГДЕ (НЕ ПОДСТРОКА(&Текст, Х, 1) ПОДОБНО "[а-я]") И Х МЕЖДУ 1 И &ДлинаТекста ИЛИ Регистр21.Х = 0
;
ВЫБРАТЬ
&x01 КАК x
ПОМЕСТИТЬ t1
ОБЪЕДИНИТЬ
ВЫБРАТЬ
&x02
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
(a.x + 2 * b.x) * (a.x + 2 * b.x) - (ВЫРАЗИТЬ((a.x + 2 * b.x) * (a.x + 2 * b.x) / &M - 0.5 КАК ЧИСЛО(10, 0))) * &M КАК x
ПОМЕСТИТЬ t2
ИЗ
t1 КАК a,
t1 КАК b
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
(a.x + 2 * b.x) * (a.x + 2 * b.x) - (ВЫРАЗИТЬ((a.x + 2 * b.x) * (a.x + 2 * b.x) / &M - 0.5 КАК ЧИСЛО(10, 0))) * &M КАК x
ПОМЕСТИТЬ t4
ИЗ
t2 КАК a,
t2 КАК b
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
(a.x + 2 * b.x) * (a.x + 2 * b.x) - (ВЫРАЗИТЬ((a.x + 2 * b.x) * (a.x + 2 * b.x) / &M - 0.5 КАК ЧИСЛО(10, 0))) * &M КАК x
ПОМЕСТИТЬ t8
ИЗ
t4 КАК a,
t4 КАК b
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
(a.x + 2 * b.x) * (a.x + 2 * b.x) - (ВЫРАЗИТЬ((a.x + 2 * b.x) * (a.x + 2 * b.x) / &M - 0.5 КАК ЧИСЛО(10, 0))) * &M КАК x
ПОМЕСТИТЬ t16
ИЗ
t8 КАК a,
t8 КАК b
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ ПЕРВЫЕ 100
(a.x + 2 * b.x) * (a.x + 2 * b.x) / &M - (ВЫРАЗИТЬ((a.x + 2 * b.x) * (a.x + 2 * b.x) / &M - 0.5 КАК ЧИСЛО(10, 0))) КАК Результат
ИЗ
t16 КАК a,
t4 КАК b Показать
Накидал запрос, который из находит значения корней из заданной таблицы аргументов. При x <= 1 млн, точность 3 знака после запятой. Работает довольно шустро, на ноутбуке 1000 значений считает за 0.2 сек:
ВЫБРАТЬ
&x
ПОМЕСТИТЬ источник
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
источник.x / 2 КАК а,
источник.x
ПОМЕСТИТЬ т1
ИЗ
источник КАК источник
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
(((т1.а + т1.x / т1.а) / 2 + т1.x / ((т1.а + т1.x / т1.а) / 2))/2 + x/(((т1.а + т1.x / т1.а) / 2 + т1.x / ((т1.а + т1.x / т1.а) / 2))/2))/2 КАК а,
т1.x
ПОМЕСТИТЬ т2
ИЗ
т1 КАК т1
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
(((т2.а + т2.x / т2.а) / 2 + т2.x / ((т2.а + т2.x / т2.а) / 2))/2 +x/(((т2.а + т2.x / т2.а) / 2 + т2.x / ((т2.а + т2.x / т2.а) / 2))/2))/2 КАК а,
т2.x
ПОМЕСТИТЬ т3
ИЗ
т2 КАК т2
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
(((т3.а + т3.x / т3.а) / 2 + т3.x / ((т3.а + т3.x / т3.а) / 2))/2 +x/(((т3.а + т3.x / т3.а) / 2 + т3.x / ((т3.а + т3.x / т3.а) / 2))/2))/2 КАК а,
т3.x
ПОМЕСТИТЬ т4
ИЗ
т3 КАК т3
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
(((т4.а + т4.x / т4.а) / 2 + т4.x / ((т4.а + т4.x / т4.а) / 2))/2 + x/(((т4.а + т4.x / т4.а) / 2 + т4.x / ((т4.а + т4.x / т4.а) / 2))/2))/2 КАК а,
т4.x
ПОМЕСТИТЬ т5
ИЗ
т4 КАК т4 Показатьx_(n+1)=x_(n)-f(x)/f'(x)
в случае квадратного корня: x_(n+1)=0.5(x_(n)+N/x_(n)), полагаем что f(x)=x^2-N
. В русской википедии тоже есть статья, но ссылку на нее не могу вставить, так как подчеркивание в названии обрезает ссылку - поищите поиском "Итерационная формула Герона". Получается, что это одно и тоже, поскольку в этой статье написано, что эту же формулу можно получить, применяя метод Ньютона к решению уравнения а - х^2 = 0.
В данной статье приведены примеры подсчета частоты символов в тексте, слов в тексте, квадратного корня с использованием такой таблицы.
В статье с помощью таких таблиц генерируются варианты расположения коробок в коробе при 3D упаковке.
В статье с помощью таких таблиц получаются веса позиций.
В статье эта таблица позволяет разбивать строки на символы.
Ну а чаще всего такие таблицы вспоминают, когда нужно сформировать "календарь" - множество дат в заданном диапазоне.
Все это реальные практические задачи.
Все необходимые для решения этой задачи функции (prototext, ЧисловаяПоследовательностьТаблицей, ЧисловаяПоследовательностьМассивом) в силу их компактности приведены в статье .
Но все же основное назначение данного метода - это не формирование таблиц для последующего использования вне запроса, а формирование таблиц для использования внутри запроса. Оказалось, что сформировать пустую таблицу значений с заданным числом строк или пронумерованную таблицу в коде все же несколько быстрее (если делать это правильно).
на складе применяется адресное хранение, адреса вида Б01-01-1, задача оптимизировать хронометраж сотрудников т.е найти ближайшую секцию для него чтобы при этом он шел в одном направлении, равномерно выполняя свою работу
это не порождающая функция, а анализирующая к сожалению , функция элементарная но именно она съедала кучу памяти и процессора пока выполнялась в виде запроса.. но у нас были и порождающие тоже постараюсь вспомнить как они выглядели и где применялись ранее (помню что по их результатам диаграмма ганта рисовалась нехилая ), чтоб не быть голословным ... да и код я все-же удалю позже т.к подписывал "неразглашение" и все такое
Без самого запроса вникнуть тяжело.
Вообще задача интересная... Можно было бы покопаться, если бы было больше исходных данных.
НомерПервойСекции = Число(Сред(НачальнаяСекция,5,2));
НомерПоследнейСекции = Число(Сред(КонечнаяСекция,5,2));
НомерТекущейСекции = Число(Сред(Секция,5,2));
dx = НомерТекущейСекции - НомерПервойСекции; dx = ?(dx<0,-dx,dx);
dy = НомерПоследнейСекции - НомерТекущейСекции; dy = ?(dy<0,-dy,dy);
Если dx>dy Тогда
Возврат КонечнаяСекция;
Иначе
Возврат НачальнаяСекция; Показатьвообщем просмотрел конфигурацию аж до июня 14 года , но там уже было исправлено, а еще раньше нет , только по памяти пытаться
но смысл запроса был таков, что на вход подаются строки типа 01 и 56 и текущая позиция тоже строка к примеру 10 нужно запросом выяснить к чему 10 ближе к 01 или к 56 выдать ответ 01 .. да это тоже не важно , а важно то что в профайлере скуля этот запрос был на первом месте по заниманию ресурсов несмотря на то что он не выбирал данные, временные таблицы уничтожались
Вообще меня эта тема довольно сильно интересует. Иногда из любви к изобретательству стараюсь делать запросами даже то, что, возможно, лучше делать кодом. Поэтому обращаю внимание на границы применимости запросной техники и возможные проблемы.
Вот он
ВЫБРАТЬ 0 КАК Х
ПОМЕСТИТЬ Регистр1
ОБЪЕДИНИТЬ
ВЫБРАТЬ 1
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ Младшие.Х + 2 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр2
ИЗ Регистр1 КАК Младшие, Регистр1 КАК Старшие
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ Младшие.Х + 4 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр4
ИЗ Регистр2 КАК Младшие, Регистр2 КАК Старшие
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ Младшие.Х + 16 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр8
ИЗ Регистр4 КАК Младшие, Регистр4 КАК Старшие
;
//////////////////////////////////////////////////////////// ///////////////////
ВЫБРАТЬ Младшие.Х + 256 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр16
ИЗ Регистр8 КАК Младшие, Регистр8 КАК Старшие
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ Младшие.Х + 65536 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр20
ИЗ Регистр16 КАК Младшие, Регистр4 КАК Старшие ПоказатьДля основания 3 и дат запрос будет иметь вид:
ВЫБРАТЬ 0 КАК Х
ПОМЕСТИТЬ Х_3
ОБЪЕДИНИТЬ ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВЫБРАТЬ 2
;
ВЫБРАТЬ 3 * Инь.Х + Янь.Х КАК Х
ПОМЕСТИТЬ Х_9
ИЗ Х_3 КАК Инь, Х_3 КАК Янь
;
ВЫБРАТЬ 9 * Инь.Х + Янь.Х КАК Х
ПОМЕСТИТЬ Х_81
ИЗ Х_9 КАК Инь, Х_9 КАК Янь
;
ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&Х1, ДЕНЬ, 81 * Инь.Х + Янь.Х) КАК Х
ИЗ Х_81 КАК Инь, Х_81 КАК Янь
ГДЕ ДОБАВИТЬКДАТЕ(&Х1, ДЕНЬ, 81 * Инь.Х + Янь.Х) <= &Х2 ПоказатьВЫБРАТЬ &Х1 КАК Х
ПОМЕСТИТЬ Х2
ОБЪЕДИНИТЬ ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&Х1, ДЕНЬ, 81 * 27)
ОБЪЕДИНИТЬ ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&Х1, ДЕНЬ, 81 * 54)
;
ВЫБРАТЬ ДОБАВИТЬКДАТЕ(Инь.Х, ДЕНЬ, РАЗНОСТЬДАТ(&Х1, Янь.Х, ДЕНЬ) / 3) КАК Х
ПОМЕСТИТЬ Х4
ИЗ Х2 КАК Инь, Х2 КАК Янь
;
ВЫБРАТЬ ДОБАВИТЬКДАТЕ(Инь.Х, ДЕНЬ, РАЗНОСТЬДАТ(&Х1, Янь.Х, ДЕНЬ) / 9) КАК Х
ПОМЕСТИТЬ Х16
ИЗ Х4 КАК Инь, Х4 КАК Янь
;
ВЫБРАТЬ ДОБАВИТЬКДАТЕ(Инь.Х, ДЕНЬ, РАЗНОСТЬДАТ(&Х1, Янь.Х, ДЕНЬ) / 81) КАК Х
ИЗ Х16 КАК Инь, Х16 КАК Янь
ГДЕ ДОБАВИТЬКДАТЕ(Инь.Х, ДЕНЬ, РАЗНОСТЬДАТ(&Х1, Янь.Х, ДЕНЬ) / 81) <= &Х2 ПоказатьВЫБРАТЬ 0 КАК Х
ПОМЕСТИТЬ Х_4
ОБЪЕДИНИТЬ ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВЫБРАТЬ 3
;
ВЫБРАТЬ 4 * Инь.Х + Янь.Х КАК Х
ПОМЕСТИТЬ Х_16
ИЗ Х_4 КАК Инь, Х_4 КАК Янь
;
ВЫБРАТЬ 16 * Инь.Х + Янь.Х КАК Х
ПОМЕСТИТЬ Х_256
ИЗ Х_16 КАК Инь, Х_16 КАК Янь
;
ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&Х1, ДЕНЬ, 256 * Инь.Х + Янь.Х) КАК Х
ИЗ Х_256 КАК Инь, Х_256 КАК Янь
ГДЕ ДОБАВИТЬКДАТЕ(&Х1, ДЕНЬ, 256 * Инь.Х + Янь.Х) <= &Х2 Показать
ВЫБРАТЬ Младшие.Х + 65536 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр20
ИЗ Регистр16 КАК Младшие, Регистр4 КАК Старшие
А тут вместо "Регистр4" не должно быть "Регистр16"?
Если скомбинировать два 16-ти разрядных регистра, то получится 32-х разрядный регистр. Там слишком большая таблица на выходе - 3,6 миллиарда строк. Для временных таблиц это запредельные величины, вряд ли нужные на практике.
ВЫБРАТЬ
ВЫРАЗИТЬ(1 КАК ЧИСЛО(10)) КАК П
ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ
ВЫБРАТЬ
2
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
ВТ1.П + ВТ2.П * 2 КАК П
ДОБАВИТЬ ВТ
ИЗ
ВТ КАК ВТ1,
ВТ КАК ВТ2
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
ВТ1.П + ВТ2.П * 6 КАК П
ДОБАВИТЬ ВТ
ИЗ
ВТ КАК ВТ1,
ВТ КАК ВТ2
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
ВТ1.П + ВТ2.П * 42 КАК П
ДОБАВИТЬ ВТ
ИЗ
ВТ КАК ВТ1,
ВТ КАК ВТ2
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
ВТ1.П + ВТ2.П * 1806 КАК П
ДОБАВИТЬ ВТ
ИЗ
ВТ КАК ВТ1,
ВТ КАК ВТ2
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
ВТ.П КАК П
ИЗ
ВТ КАК ВТ ПоказатьВы можете заказать платную консультацию или разработку у автора. Будет создан приватный заказ на «Бирже заказов» для автора.
№ 90367
Создание 15.09.11 02:04
Обновление 01.11.19 14:55
Просмотры 86570
Загрузки 156
Рейтинг
293
Комментарии 91
Код открыт Да
Рубрики Запросы
Кому Разработчик
Тип файла Архив с данными
Платформа 1С:Предприятие 8
Конфигурация 1C:Бухгалтерия
Операционная система Не имеет значения
Страна Не имеет значения
Отрасль Не имеет значения
Налоги Не имеет значения
Вид учета Не имеет значения
Доступ к файлу Абонемент ($m)