Вопросы производительности, оптимизация кода. Бизнес-логика

31.03.24

Разработка - Рефакторинг и качество кода

Минимизация обращений к серверу на конкретном примере.

Сразу скажу, я не собирался этого делать. Собирался я выложить здесь некоторый отчетик за стартманей несколько, но немножко застрял на процедуре заполнения табличной части документа "Оказание услуг".

По всей видимости, это профессиональная деформация. Нет, в боевых условиях я легко прохожу мимо того, что меня не касается. Но сейчас торопиться совершенно некуда, поэтому пусть будет.

Итак. Есть штатная фича для заполнения указанной табличной части некими услугами, повторяющимися из месяца в месяц.

По кнопе на форме документа...

 

Кнопка заполнения в Оказании услуг

 

... управление передается в следующую процедуру модуля документа:

Процедура ЗаполнитьПоВидуВзаиморасчетов() Экспорт

	ВалютаРегламентированногоУчета	= Константы.ВалютаРегламентированногоУчета.Получить();
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("ДатаСреза",			Дата);
	Запрос.УстановитьПараметр("Организация",		Организация);
	Запрос.УстановитьПараметр("ВидДоговора",		Перечисления.ВидыДоговоровКонтрагентов.СПокупателем);
	Запрос.УстановитьПараметр("ВидВзаиморасчетов",	ВидВзаиморасчетов);
	Запрос.УстановитьПараметр("ВалютаРегламентированногоУчета",	ВалютаРегламентированногоУчета);
	
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ДоговорыКонтрагентов.Владелец КАК Контрагент,
	|	ДоговорыКонтрагентов.Владелец.Наименование КАК НаименованиеКонтрагента,
	|	ДоговорыКонтрагентов.Ссылка КАК ДоговорКонтрагента,
	|	ДоговорыКонтрагентов.ТипЦен КАК ТипЦен,
	|	ДоговорыКонтрагентов.ТипЦен.ЦенаВключаетНДС КАК ЦенаВключаетНДС
	|ИЗ
	|	Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
	|ГДЕ
	|	ДоговорыКонтрагентов.ПометкаУдаления = ЛОЖЬ
	|	И ДоговорыКонтрагентов.ЭтоГруппа = ЛОЖЬ
	|	И ДоговорыКонтрагентов.Организация = &Организация
	|	И ДоговорыКонтрагентов.ВидДоговора = &ВидДоговора
	|	И ДоговорыКонтрагентов.ВидВзаиморасчетов = &ВидВзаиморасчетов
	|	И ДоговорыКонтрагентов.ВалютаВзаиморасчетов = &ВалютаРегламентированногоУчета
	|	И ДоговорыКонтрагентов.СрокДействия = ДАТАВРЕМЯ(1, 1, 1)
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	ДоговорыКонтрагентов.Владелец,
	|	ДоговорыКонтрагентов.Владелец.Наименование,
	|	ДоговорыКонтрагентов.Ссылка,
	|	ДоговорыКонтрагентов.ТипЦен,
	|	ДоговорыКонтрагентов.ТипЦен.ЦенаВключаетНДС
	|ИЗ
	|	Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
	|ГДЕ
	|	ДоговорыКонтрагентов.ПометкаУдаления = ЛОЖЬ
	|	И ДоговорыКонтрагентов.ЭтоГруппа = ЛОЖЬ
	|	И ДоговорыКонтрагентов.Организация = &Организация
	|	И ДоговорыКонтрагентов.ВидДоговора = &ВидДоговора
	|	И ДоговорыКонтрагентов.ВидВзаиморасчетов = &ВидВзаиморасчетов
	|	И ДоговорыКонтрагентов.ВалютаВзаиморасчетов = &ВалютаРегламентированногоУчета
	|	И НАЧАЛОПЕРИОДА(ДоговорыКонтрагентов.СрокДействия, МЕСЯЦ) >= НАЧАЛОПЕРИОДА(&ДатаСреза, МЕСЯЦ)
	|
	|УПОРЯДОЧИТЬ ПО
	|	НаименованиеКонтрагента";
	
	ТаблицаДоговоров	= Запрос.Выполнить().Выгрузить();
	
	ЦеныНоменклатуры = Новый Соответствие;
	
	Если ЗначениеЗаполнено(Номенклатура) Тогда
		
		МассивТиповЦен	= ОбщегоНазначения.ВыгрузитьКолонку(ТаблицаДоговоров, "ТипЦен", Истина);
		
		Для Каждого ТипЦен Из МассивТиповЦен Цикл
			Цена	= 0;
			Если ЗначениеЗаполнено(ТипЦен) Тогда
				Цена = Ценообразование.ПолучитьЦенуНоменклатуры(Номенклатура,
							ТипЦен, Дата, ВалютаРегламентированногоУчета, 1, 1);
			КонецЕсли;
			ЦеныНоменклатуры.Вставить(ТипЦен, Цена);
		КонецЦикла;
		
	КонецЕсли;
	
	Для каждого СтрокаТаблицы Из ТаблицаДоговоров Цикл
		
		НоваяСтрока	= Контрагенты.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТаблицы);
		
		Документы.ОказаниеУслуг.ЗаполнитьСчетаУчетаВСтрокеТабличнойЧасти(ЭтотОбъект, НоваяСтрока, "Контрагенты");
		
		НоваяСтрока.Количество	= 1;
		Если ЗначениеЗаполнено(СтрокаТаблицы.ТипЦен)
			И ЦеныНоменклатуры.Получить(СтрокаТаблицы.ТипЦен) <> Неопределено Тогда
			
			НоваяСтрока.Цена = УчетНДСКлиентСервер.ПересчитатьЦенуПриИзмененииФлаговНалогов(
				ЦеныНоменклатуры.Получить(СтрокаТаблицы.ТипЦен),
				СтрокаТаблицы.ЦенаВключаетНДС,
				СуммаВключаетНДС,
				УчетНДСВызовСервераПовтИсп.ПолучитьСтавкуНДС(СтавкаНДС));
			
			ОбработкаТабличныхЧастейКлиентСервер.РассчитатьСуммуТабЧасти(НоваяСтрока);
			
			НоваяСтрока.СуммаНДС = УчетНДСКлиентСервер.РассчитатьСуммуНДС(
				НоваяСтрока.Сумма,
				СуммаВключаетНДС,
				УчетНДСВызовСервераПовтИсп.ПолучитьСтавкуНДС(СтавкаНДС));
			
		КонецЕсли;
		
	КонецЦикла;

КонецПроцедуры

Это БП версии 3.0.150.29, так, на всякий случай. А платформа у меня сейчас 8.3.23.2040.

Что надо отметить, так это две вещи. Во-первых, это не пример того, что надо всё бросить и оптимизировать. В сколько-нибудь нагруженных системах вклад этого куска кода исчезающе мал.

Во-вторых, это не вот какие неумехи программисты вендора, а я весь в белом. Это не так. Вообще, с практикой работы 1сником приходит понимание, что критика чужого кода - это самое последнее, чем ты можешь заняться, и то при условии, что хочешь произвести о себе самом не самое лучшее впечатление.

Так что, прошу рассматривать представленный кейс не как руководство к действию, но как частное неавторитетное мнение надменного и очень неприятного человека.

А так, с учетом вышеизложенного, имеем классику жанра: запрос и в цикле по результату - пост-обработку. Причем здесь - целых ДВА (!) подряд цикла.

Но, по порядочку.

В запрос передаются пять параметров., из них три - необходимы, они определены в вызывающей форме. Но два из них, ВидДоговора и ВалютаРегламентированногоУчета должны быть определены в теле запроса, а не через точку до него. Да, повторюсь, влияние на производительность ничтожно, можно сказать - "ловля блох". Но есть вещи, за которые глаз цепляется сам, если в твоей жизни было такое, что склад вставал и шел курить, поминая "эту вашу одинес". Два этих параметра здесь - это два обращения к базе данных, когда наш main запрос еще даже не начал формироваться.

Это было "А". "Б" у нас будут замечания не к производительности, но к бизнес-логике запроса.

Во-первых.  Задействован реквизит справочника СрокДействия. Он должен быть либо не заполнен, либо быть больше, чем начало месяца даты заполняемого документа. Условие ИЛИ известно тем, что про него говорят "очень тормозит". Наверное, поэтому здесь решили по два раза выполнить запросы к таблице ДоговорыКонтрагентов в соединении с Контрагенты и ТипыЦен. Так, наверное, быстрее. Мы не будем прогонять это решение через тесты, просто сделаем по-своему.

Во-вторых. НЕ задействован реквизит Дата ("Дата договора"). То есть, если пользователь создаст карточку договора, который начнет действовать через полгода, то все эти полгода он будет вручную удалять строчки из ОказанияУслуг. Если, конечно, заметит эти левые строчки.

Мы сделаем так, что этот реквизит либо пустой, либо не больше, чем конец месяца даты заполняемого документа. Проверку условия СрокДействия>=Дата оставим на совести алгоритма записи карточки договора.

В результате творческого порыва, запрос получается таким:

ВЫБРАТЬ
|    ДАТАВРЕМЯ(1, 1, 1) КАК ПустаяДата,
|    НАЧАЛОПЕРИОДА(&ДатаСреза, МЕСЯЦ) КАК НачалоМесяца,
|    КОНЕЦПЕРИОДА(&ДатаСреза, МЕСЯЦ) КАК КонецМесяца
|ПОМЕСТИТЬ Даты
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|    ДоговорыКонтрагентов.Ссылка КАК Ссылка,
|    ДоговорыКонтрагентов.Владелец КАК Владелец,
|    ДоговорыКонтрагентов.ТипЦен КАК ТипЦен,
|    ДоговорыКонтрагентов.Дата КАК Дата,
|    ДоговорыКонтрагентов.СрокДействия КАК СрокДействия
|ПОМЕСТИТЬ Договоры
|ИЗ
|    Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
|        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Константа.ВалютаРегламентированногоУчета КАК ВалютаРегламентированногоУчета
|        ПО ДоговорыКонтрагентов.ВалютаВзаиморасчетов = ВалютаРегламентированногоУчета.Значение
|        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Даты КАК Д
|        ПО (ДоговорыКонтрагентов.Дата = Д.ПустаяДата
|                ИЛИ ДоговорыКонтрагентов.Дата <= Д.КонецМесяца)
|            И (ДоговорыКонтрагентов.Дата = Д.ПустаяДата
|                ИЛИ ДоговорыКонтрагентов.Дата >= Д.НачалоМесяца)
|ГДЕ
|    НЕ ДоговорыКонтрагентов.ПометкаУдаления
|    И ДоговорыКонтрагентов.Организация = &Организация
|    И ДоговорыКонтрагентов.ВидДоговора = ЗНАЧЕНИЕ(Перечисление.ВидыДоговоровКонтрагентов.СПокупателем)
|    И ДоговорыКонтрагентов.ВидВзаиморасчетов = &ВидВзаиморасчетов
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|    Договоры.Ссылка КАК ДоговорКонтрагента,
|    Договоры.Владелец КАК Контрагент,
|    Договоры.ТипЦен КАК ТипЦен,
|    КА.Наименование КАК НаименованиеКонтрагента,
|    ТЦ.ЦенаВключаетНДС КАК ЦенаВключаетНДС
|ИЗ
|    Договоры КАК Договоры
|        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ТипыЦенНоменклатуры КАК ТЦ
|        ПО Договоры.ТипЦен = ТЦ.Ссылка
|        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК КА
|        ПО Договоры.Владелец = КА.Ссылка

Как видите, я вставил сюда дважды "ИЛИ" в условие внутреннего соединения, дважды потому, что включил в бизнес-логику дату договора. Мой внутренний голос говорит, что так лучше. Где правда, покажет объективный контроль.

Но это еще не все.

Я исключил условие "НЕ ЭтоГруппа".

За свою практику мне ни одного раза не довелось встречаться с тем, чтобы пользователи использовали папки в справочнике ДоговорыКонтрагентов.

Но это не значит, что они не могут попробовать, вендор оставил им это:

 

 

Признаюсь, это я увидел в первый раз (как многому надо еще научиться!).

И, конечно, сразу же и создал папку...

 

 

.., и попробовал в нее перенести элемент...

 

 

... но у меня ничего не получилось. Полагаю, что не получится и у пользователей. Поэтому просто выкинул "ЭтоГруппа" из запроса.

Но и это еще не все!!!

В первом цикле обхода результата запроса (при заполненной номенклатуре) выполняется следующий код:

Функция ПолучитьЦенуНоменклатуры(Номенклатура, ТипЦен, Дата, Валюта = Неопределено, Курс = 0, Кратность = 1) Экспорт
	
	ПолученнаяЦена = 0;
	
	Если Не ПравоДоступа("Чтение", Метаданные.РегистрыСведений.ЦеныНоменклатуры) Тогда
		Возврат ПолученнаяЦена;
	КонецЕсли;
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("Дата",         Дата);
	Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
	Запрос.УстановитьПараметр("ТипЦен",       ТипЦен);
	Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
	|	ЦеныНоменклатуры.Цена,
	|	ЦеныНоменклатуры.Валюта
	|ИЗ
	|	РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата, Номенклатура = &Номенклатура И ТипЦен = &ТипЦен) КАК ЦеныНоменклатуры";

	Выборка = Запрос.Выполнить().Выбрать();
	Если Выборка.Следующий() Тогда
		ПолученнаяЦена = Выборка.Цена;
		ВалютаЦены     = Выборка.Валюта;
	КонецЕсли;

	Если НЕ (ВалютаЦены = Валюта) И НЕ (Валюта = Неопределено) И НЕ (ВалютаЦены = Неопределено) Тогда

		СтруктураКурсаЦены = РаботаСКурсамиВалют.ПолучитьКурсВалюты(ВалютаЦены, Дата);
		ПолученнаяЦена     = РаботаСКурсамиВалютБПКлиентСервер.ПересчитатьИзВалютыВВалюту(
			ПолученнаяЦена, ВалютаЦены, Валюта, 
		    СтруктураКурсаЦены.Курс, Курс, 
		    СтруктураКурсаЦены.Кратность, Кратность);
			
		ПолученнаяЦена     = ОкруглитьЦену(ПолученнаяЦена, ТипЦен);

	ИначеЕсли Валюта = Неопределено Тогда
		Валюта = ВалютаЦены;
	КонецЕсли;

	Возврат ПолученнаяЦена;

КонецФункции // ПолучитьЦенуНоменклатуры()

Поместим выход нашего запроса во временную таблицу и соединим ее с ценовым регистром. Валюта регламентированного учета у нас рубли (а у вас?), поэтому все эти ваши ПересчитатьИзВалютыВВалюту мы просто игнорируем.

Окончание нашего запроса теперь выглядит так:

|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|	Договоры.Ссылка КАК ДоговорКонтрагента,
|	Договоры.Владелец КАК Контрагент,
|	Договоры.ТипЦен КАК ТипЦен,
|	КА.Наименование КАК НаименованиеКонтрагента,
|	ТЦ.ЦенаВключаетНДС КАК ЦенаВключаетНДС
|ПОМЕСТИТЬ ВыбранныеДоговоры
|ИЗ
|	Договоры КАК Договоры
|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ТипыЦенНоменклатуры КАК ТЦ
|		ПО Договоры.ТипЦен = ТЦ.Ссылка
|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК КА
|		ПО Договоры.Владелец = КА.Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|УНИЧТОЖИТЬ Договоры
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|	ВыбранныеДоговоры.ДоговорКонтрагента КАК ДоговорКонтрагента,
|	ВыбранныеДоговоры.Контрагент КАК Контрагент,
|	ВыбранныеДоговоры.ТипЦен КАК ТипЦен,
|	ВыбранныеДоговоры.НаименованиеКонтрагента КАК НаименованиеКонтрагента,
|	ВыбранныеДоговоры.ЦенаВключаетНДС КАК ЦенаВключаетНДС,
|	isnull(ЦеныНоменклатуры.Цена, 0) КАК Цена
|ИЗ
|	ВыбранныеДоговоры КАК ВыбранныеДоговоры
|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ДатаСреза, Номенклатура = &Номенклатура) КАК ЦеныНоменклатуры
|		ПО ВыбранныеДоговоры.ТипЦен = ЦеныНоменклатуры.ТипЦен

От первого цикла запросов мы избавились.

Что происходит во втором?

Во-первых, заполняются счета учета.

Во-вторых, если в договоре указан тип цен (и есть номенклатура), то цена, сумма и сумма НДС пересчитываются в зависимости от флага ЦенаВключаетНДС в типе цены.

Ну, вы уже поняли :))))

Если бы передо мной стояла задача добиться от этого куска кода высокой производительности, я бы поступил со вторым циклом точно так же, как с первым. А именно, перенес бы логику вызываемых процедур  ЗаполнитьСчетаУчетаВСтрокеТабличнойЧасти, ПересчитатьЦенуПриИзмененииФлаговНалогов, РассчитатьСуммуТабЧасти и РассчитатьСуммуНДС в тело запроса, а потом загрузил бы результат в заполняемый документ.

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

быстродействие оптимизация кода

См. также

Результаты ревью кода 1500+ решений каталога Инфостарт: наиболее частые ошибки разработчиков в коде

Рефакторинг и качество кода Платформа 1С v8.3 Бесплатно (free)

Поделюсь своим опытом аудита кода авторских продуктов с Infostart.ru как одним из элементов применения DevOps-практик внутри Инфостарт. Будет настоящий код, боевые скриншоты, внутренние мемы от команды ИТ-лаборатории Инфостарт и прочее мясо – все, что любят разработчики.

10.04.2024    6908    artbear    84    

81

Ниндзя-код

Рефакторинг и качество кода Платформа 1С v8.3 Россия Бесплатно (free)

Предлагаю вашему вниманию советы мастеров древности. Программисты прошлого использовали их, чтобы заострить разум тех, кто после них будет поддерживать код. Гуру разработки при найме старательно ищут их применение в тестовых заданиях. Новички иногда используют их ещё лучше, чем матёрые ниндзя. Прочитайте их и решите, кто вы: ниндзя, новичок или, может быть, гуру? (Адаптация статьи "Ниндзя-код" из учебника JavaScript)

01.04.2024    2460    DrAku1a    15    

33

Практическое программирование: когда скорость важнее совершенства

Рефакторинг и качество кода Бесплатно (free)

В новом материале мы анализируем, как в программировании баланс между быстротой разработки и тщательной проработкой кода влияет на конечный продукт. Обсуждаем, почему иногда важнее сосредоточиться на скорости выполнения проекта, и когда можно позволить себе уступить в качестве ради достижения бизнес-целей.

01.04.2024    647    Prepod2003    6    

2

Когда понадобился новый оператор

Рефакторинг и качество кода Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Когда понадобился новый оператор, но его нет в синтакс-помощнике, что делать?

18.03.2024    1381    ZhokhovM    4    

4

Когда разработчик платформы не добавил проверку препроцессоров

Рефакторинг и качество кода Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Когда разработчик платформы решил пойти на кухню за кофе, а проверку препроцессоров не добавил, и вот тут-то и началось: "Что, опять все сломалось? Ну и кофе же я забыл сделать!".😅

18.03.2024    3059    ZhokhovM    4    

9

Реструктуризация - бесконечная история

Рефакторинг и качество кода Платформа 1С v8.3 Бесплатно (free)

При разработке программ требуемый функционал ставят на первое место, но есть еще и архитектура программы. На горизонте 5-10 лет она становится важнее функционала, который должен работать при масштабировании и росте данных. Реструктуризация 5 терабайтной базы 1С 8.2 в формат 1С 8.3, складывает весь пазл архитектурных просчетов, которые сделали ради функционала. Как это исправить? - для разработки правильной архитектуры, нужно всего лишь сместить фокус с функционала и подумать о «вечном».

29.09.2023    2131    1CUnlimited    15    

23

Чистый код. Мой взгляд на жизнь в макаронных джунглях. Часть 2

Рефакторинг и качество кода Платформа 1С v8.3 Конфигурации 1cv8 Россия Бесплатно (free)

Коротко о том, как я перестал быть создателем макаронного кода и непроходимых джунглей методов и модулей. Расскажу о том, что реально применяю на практике с примерами при разработке (а в основном доработке) в типовых конфигурациях 1С. Комментарии очень приветствуются.

27.09.2023    7238    Lemmonbri    136    

37
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. tango 543 30.03.24 22:38 Сейчас в теме
всё по честному, без обмана
Прикрепленные файлы:
2. ivanov660 4349 31.03.24 12:15 Сейчас в теме
Утверждение "Мой внутренний голос говорит, что так лучше." - за гранью моего понимания для технической статьи, особенно по оптимизации, где порой важна каждая мелочь. На мой взгляд, должна прослеживаться четкая последовательность в виде: утверждение - доказательство.

Я исключил условие "НЕ ЭтоГруппа".

За свою практику мне ни одного раза не довелось встречаться с тем, чтобы пользователи использовали папки в справочнике ДоговорыКонтрагентов.


Вот я часто встречаюсь, что бухгалтера разбивают договоры по группам - комиссия, займ и т.д. И само наличие условия НЕ не снижает производительность как таковое, перепишите так ЭтоГруппа=Ложь, если напрягает НЕ.

В общем, мне не понравилось.
Orlando Skibraves; EvgeniyOlxovskiy; charushkin; +3 Ответить
3. tango 543 31.03.24 13:34 Сейчас в теме
(2) у каждого свой фломастер
почему компьютер - арт, а не сайенс
есть такое слово - "чуйка" (объяснять значение не буду. потому что мне не нравится быть в роли учителя)

И если вы таки любите детали, то присмотритесь, как условие по папке написано у вендора. (извините за совет)
--
пс: еще раз извините, забыл поблагодарить за комментарий. Спасибо
__
пс: еще раз о деталях и папках. Я привел скрин, где БП отказалась переместить элемент в папку. Попробуйте на демо-базе, может быть, у вас получится, с удовольствием прочитаю вашу статью об этом
5. ivanov660 4349 31.03.24 14:01 Сейчас в теме
(3)
1. Для художественного произведения или области работы с сотрудниками, такой подход приемлем и звучит здорово. Но в данном случае, часть озвученных вами решений не выдерживает критики. О чем я и написал.
Приведите доказательства того что ваше предложение действительно оптимизирует, тогда скорее всего все вопросы снимутся.
2. Зачем ссылаться на неудачное решение? На мой взгляд, разумнее равняться на лучшего.
Единственный путь стать умнее — играть с более сильным противником

Эмануэль Ласкер
P.S. Дали статью - получите замечания и защищайте свою позицию.
EvgeniyOlxovskiy; +1 Ответить
6. tango 543 31.03.24 14:13 Сейчас в теме
(5) и еще раз спасибо за комментарий (критику)
критика - это очень важно для нас.

"чуйка" - это не только в коммуникациях с живыми организмами, но и со вселенной, как в целом, так и по кусочкам
а уж в науке (и искусстве) ... в 1с так вообще известен Гений 1С :))))

Доказательства? Вам нужны доказательства, что предварительные запросы в базу для получения постоянных параметров - это хуже, чем их вычисление в основном запросе?
Вы сериозно? нет, мне не улыбается спорить со специалистом, как-то сумевшим заработать 4 336 рейтинга на ИС. но было бы интересно, если бы вы обосновали свои сомнения

Или вам нужны доказательства, что куча запросов в цикле обхода результата первого (основного) запроса - это чистое зло? Стесняюсь спросить. на чем вы так прокачали свои компетенции

Или вы конкретно о том, что выбрасывать условие "НЕ ЭтоГруппа" (или "ЭтоГруппа=ЛОЖЬ" - на ваш выбор) - это не правильно?

Попрошу сильного противника привести какие-нибудь аргументы, кроме "мне не понравилось"
Прикрепленные файлы:
8. ivanov660 4349 31.03.24 16:39 Сейчас в теме
(6) Давайте не будем уходить в сторону от дискуссии и переходить на личности - это не профессионально.
Вы написали статью - это похвально и заслуживает уважения, но раз так получилось, то на мой взгляд Вы должны отстаивать то что написано в статье. И да, для меня доказательства важны, я на слово не верю.

Давайте расскажу про некоторые моменты более подробно:

1. Обсудим условие НЕ.
Эффективность условий в большинстве случаев связана с использованием планировщиком СУБД индексов. Иными словами, если существуют индексные таблицы подходящие к каким-либо условиям отборов, то запрос будет более эффективен. Т.к. в противном случае будет использоваться полное сканирование, а это перебор всей таблицы - в противовес получения нескольких значений сразу.

Индексы, в основном, могут использоваться для операторов равно (=), больше (>), меньше (<) и их комбинаций. И не могут использоваться для условий НЕ. Но это не значит, что требуется всегда избавляться от такого условия. В некоторых случаях такие условия могут довольно сильно порезать количество данных передаваемых на следующий уровень плана запроса, а это однозначно большой плюс.

В данном примере, индексов подходящих скорее всего не будет и будет использоваться полное сканирование. Соответственно, удаление условия НЕ к выигрышу не приведет. А может добавит как раз проблем, если вдруг каким-то образом в результат пролезут группы, а дальнейший код будет пытаться обрабатывать их как элементы.

2. Про получение некоторых данных заранее.
- Часто получают некоторые данные заранее, если планируется использовать их потом в нескольких местах сразу.
- Также значительно упрощается сам запрос - а это очень важно.
- Относительно накладных затрат, то получение валюты будет очень быстро и не скажется заметно на общей производительности этого куска кода в общем. Попробуйте взять и сравните, какую эффективность вы получите изменив такую конструкцию с базовой. Если будет 2%, то даже смысла об этом нет говорить.
- Вот как раз создание огромных конструкций запросов, который делает все и сразу приведет к тому, что поддерживаться такой код станет проблематично и не возможно. Поэтому такие оптимизации должны быть четко обоснованы, чтобы польза была больше чем сопутствующее проблемы.

3. Про запросы в цикле.
Запросы в цикле конечно это плохо, но опять же тут должна быть здравая логика при оптимизации. В типовом коде видна модульность, его просто дорабатывать, он достаточно понятен. Если переписать этот кусок кода на один запрос, то все эти преимущества исчезают.
Дополнительно уже в самом коде существует оптимизация запроса в цикле через кэширование (цены номенклатуры = Соответствие), т.е. если был один раз получен уже тип цен, то второй раз выполняться запрос уже не будет.
Поэтому какой эффект будет в случае предложенной оптимизации мне не понятно?

P.S. Все пытаться оптимизировать нет смысла. И всегда надо придерживаться критерия эффективности и целесообразности выполненных работ.
itmind; triviumfan; ixijixi; webester; EvgeniyOlxovskiy; charushkin; +6 Ответить
9. tango 543 31.03.24 16:58 Сейчас в теме
(8) Дискуссия? Мне, конечно, льстит внимание из высшей лиги ИС (хотя предпочел бы срубить рейтинга от "я-не-волшебник-только-учусь"), но где вы здесь видите дискуссию?

1. по поводу "НЕ" - ваша дискуссия происходит только в вашей голове. У вендора есть проверка на группу. У меня - нет. Как это сделано, через "НЕ Это группа" или через "ЭтоГруппа=ЛОЖЬ", в моем тексте не обсуждается от слова никак.

2. Мы готовим запрос. А перед этим выполняем еще два обращения к базе. Я вполне допускаю мысль, что в каких-то ситуациях это (может быть, весьма сомнительно) даст выигрыш. Но доказательство, в виде замеров и т.д., требует именно утверждение, что лучше будет с предварительными запросами неизменных значений параметров, но не наоборот. Наоборот - это очевидное априорное знание, не подлежащее обсуждению (дискуссии)

3. Если вам не понятно, почему не следует делать запросы в цикле по результату запроса, я помочь вам ничем не смогу, и уж точно не стану участвовать в дискуссии на эту тему. Я вовсе не против практики программистов вендора облегчить себе жизнь путем повторного использования каких-то кусков кода. Если нет ООП, то пусть хоть так. Но не в том случае, когда конкретное место приводит к зависанию базы. В этом случае удобство автообновления приносится в жертву работоспособности. Не о чем дискутировать (имхо)

пс: все оптимизировать не надо (и это есть в тексте). Оптимизировать надо то, на чем склад выходит покурить. Конкретно это место из типовой БП мною использовано в статье (случайно, просто на глаза попалось) для иллюстрации очевидных (казалось бы) вещей - вся логика в одном запросе, результат заполняет нужную таблицу простым выгрузить/загрузить (копипастом, если угодно). Уверен, что таких мест в типовой - полна коробушка, просто в силу принцыпа 1С+ООП. Но лезть с оптимизацией надо только туда, куда надо
12. tango 543 01.04.24 10:41 Сейчас в теме
(9) вот. как раз то, о чем я говорю в (11) о носителях "шашечек".
Два дизлайка.
Люди, готовые делать три запроса к базе вместо одного.
Не видящие "ничего такова" в запросах в цикле по результату запроса.
И эти люди предъявляют мне "неприятность в общении".

Конечно, мне неприятно с вами общаться. Просто потому, что умело улыбаясь клиенту, вы замещаете рабочие места тех, кто умеет в запросы.
Прикрепленные файлы:
4. ixijixi 1802 31.03.24 13:59 Сейчас в теме
Помимо вопросов производительности и быстродействия разработчикам приходится также заниматься вопросами унификации. Например, указанный метод пересчета курсов вызывается в БП КОРП 240 раз (а также почти в таком же виде присутствует в УТ, КА и ERP). Следуя Вашей логике придется их переписать, ни разу не ошибиться и получить прирост быстродействия в 2% (наугад говорю, но и у Вас замеров нет, не факт, что будет больше).
Прикрепленные файлы:
0x00; EvgeniyOlxovskiy; +2 Ответить
7. tango 543 31.03.24 14:22 Сейчас в теме
(4) Замеров нет, да :))))
Я не планировал эту статью, просто зацепился глаз по случаю, вот и получилось.
Я не предлагал переписать пересчет из валюты в валюту. Я от него просто отказался.
В "универсальном" решении, возможно (да даже наверняка) естественным ходом разработчика является "Объе́ктно ориенти́рованное программи́рование (сокр. ООП)". Ну, как всегда с некоей 1с-кастомизацией принятых среди "настоящих" программистов фенечек.

Но, здесь, во-первых, речь идет об оптимизации конкретной - российской! - бухгалтерии, которой ЗАКОНОДАТЕЛЬНО предписано ведение расчетов в рублях. С момента этого запрета возникают вопросы к существованию константы "ВалютаРегламентированногоУчета". Разумеется, это не относится к разработке "универсальных" решений

И во-вторых, при работе с конкретной базой программист должен быть достаточно погружен в предмет, чтобы принять решение, надо ему пересчитывать валюты или не надо. Если пересчет производится в критически узком месте, где он реально вывешивает систему, то надо переписывать запрос, без тени сомнения послав по известному адресу
любую всякую унификацию вендора.
__
и да, спасибо что прочитали и даже потратили время на ответ
16. andrew.ab 220 04.04.24 17:45 Сейчас в теме
(7) отказаться от валюты - отказаться от вэд - отказаться импорта и. т. п. Давайте на учёт на счетах перейдём и переделывать ничего не надо будет)))
10. webester 26 01.04.24 05:53 Сейчас в теме
частное неавторитетное мнение надменного и очень неприятного человека.

У меня надо сказать по тому ваших комментариев которые видел раньше тоже сложилось такое мнение. Никаких претензий и сейчас уже даже сказать не могу почему так вышло. Чисто субъективная оценка. Но возможно вам нужно быть чуть мягче к другим.

что критика чужого кода - это самое последнее, чем ты можешь заняться

Называется рефакторинг. Делает и код и программиста (который знает, что его код будут анализировать)лучше. Настаиваю, чтобы коллеги смотрели мой код и сам стараюсь заниматься тем же. Анализ, обсуждение (ну и как следствие критика) кода с автором всегда нужное и частое важное дело. Но есть нюанс. Автор этого кода 1С. Писать надо ему.

Да. Здесь классическая ошибка начинающего. Автор применил функцию которая использует запрос. Возможно даже не задумываясь, что он там есть. Наступал тоже на такие грабли по первости. Бывает. Ничего страшного.
ЗЫ так и не понял, каким боком в комменты попал геня1С?
11. tango 543 01.04.24 10:20 Сейчас в теме
Спасибо за отзыв.
"такое мнение" - вы не одиноки. Но аргументы оппонентов свидетельствуют, что я скорее прав. Особенно дизлайки без аргументов. Православным есть батюшки, остальным - психотерапевты. Но я согласен, что ехать лучше с шашечками. Проблема возникает, когда шашечки означают не "такси", а "ехать".

Я имел ввиду заочную критику. Когда "мой предшественник такого тут у вас наворотил, вы не представляете!".
Хотя бывает, что молчать нельзя. Как, например, о франчайзи, изменивших режим оперативного проведения у клиента.
Но в данном случае я просто попытался смягчить критику в адрес вендора. Быть, так сказать, не надменным и приятным.

1С. Писать надо ему
- так-то 1С на данной площадке на паях с Доржи. Но текст адресован не тем программистам, которые облегчают себе свой труд повторным использованием кода, (вместо того, чтобы конструировать текст запросов :) ).
А тем программистам, которые представляют 1с в штате клиента, когда 1с вдруг почему-то не работает. И огребают не дивидендов.

И я не согласен все валить здесь на недостаточную квалификацию сотрудников 1С. Очевидно же, что относительно штата вендора это было бы как минимум некорректно. Нет, это осознанное множественное применение куска кода. И я уверен, что это не "бывает", что в типовых - это широчайше распространенный феномен.

Геня (чуйка - озарение - гениально!) здесь присутствует как доказательство того, что поверять алгеброй гармонию - не всегда удачная идея, и не всегда получается. Но если ты - не гений, у тебя нет другого выхода, надо замерять производительность.
13. triviumfan 93 01.04.24 16:53 Сейчас в теме
Согласен с коллегами, что для полноты картины не хватает замеров.
Ещё можно было бы пересчет по курсу добавить, в конфе уже есть примеры решения сей задачи в запросах.
14. tango 543 03.04.24 15:26 Сейчас в теме
(13) спасибо за отзыв.
замеров действительно не хватает
замеры следует ожидать от тех специалистов 1с, которые утверждают, что:
а) исключение мусорного условия не повлияет на производительность
б) три запроса быстрее одного
в) выполнение запросов в цикле по результату запроса вместо получения заполненной выходной таблицы в одном запросе не влияет на производительность, а если и влияет (немножко-немножко), то ценность времени разработчика гораздо больше

Все эти утверждения не выглядят сколько-нибудь квалифицированными без замеров
И эти утверждения не принадлежат автору, как бы надменен и очень неприятен он ни был

с тезисами комментаторов по п.в) я не соглашусь в явном виде.
а) простой иного склада может превысить капитализацию всего вендора
б) повторными кусками кода облегчается не жизнь кодера, а жизнь надзирателя за кодерами
15. tango 543 03.04.24 15:34 Сейчас в теме
(14) Выскажусь даже более сильно.
Упреки в сторону 1с в проигрыше по производительности и надежности всяким там загнивающим сапам с акцаптами, вызваны как раз парадигмой использования в цикле где-то там лежащих кусков кода
17. itmind 310 08.04.24 04:51 Сейчас в теме
Согласен, что код не оптимальный и в типовом коде 1с очень много нелогичных мест, неправильной архитектуры, "джуновского кода".
Но и в статье мало технических деталей, например не разобраны планы запросов. Для новичка будет не понятно, чем ваше решение лучше штатного, никаких подтверждений нет в статье.

Вы ускорили на 0,3 секунды выполнение процедуры потратив на это, условно, 3000 руб. работодателя. Я думаю, что изменения, которые никто никогда не замит кроме самого разработчика не стоят денег заказчика. (да и личного времени программиста тоже).
bayselonarrend; +1 Ответить
Оставьте свое сообщение