Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
18 апр 2024, 08:07

Какую литерату почитать по оптимизации кода?

Автор Рексарыч, 12 мая 2015, 11:32

0 Пользователей и 1 гость просматривают эту тему.

Рексарыч

Привет, друзья.

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

Пример отрывка кода:


ГодМесяцДень=Дата(2015,02,01,0,0,0);

//берём объект из РС
Карта = новый запрос("
    |Выбрать //первые 50
| *
|Из
| Справочник.РесурсныеСпецификации");

Карта = Карта.Выполнить().Выбрать();

//пробегаемся по всем обектам РС
Пока Карта.Следующий() Цикл

Если НЕ Карта.Ссылка.ЭтоГруппа Тогда

Строка=Карта.Ссылка.ПолучитьОбъект();

сообщить("РС = " + Строка.Наименование);

//Заполняем Дату
Сообщить("1 = " + Строка.НачалоДействия);
Строка.НачалоДействия=ГодМесяцДень;
Сообщить("2 = " + Строка.НачалоДействия);

Строка.Записать();

КонецЕсли;

КонецЦикла;


Как видите - код рабочий, но явно не оптимизированный. Если кто знает нужную мне литература, то подскажите пожалуйста.

MuI_I_Ika

Начните с любой книжки по 1С. Там полно оптимизированного кода. Радченко например.

LexaK

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

Небольшой разбор вашего кода

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

2. Сразу же в запросе установите отбор по нужным условиям
|...
|Из
|    Справочник.РесурсныеСпецификации Спр
|Где
|    Не Спр.ЭтоГруппа
|//и   Спр.НачалоДействия <> ДатаВремя(2015,2,1)
|и   Спр.НачалоДействия <> &ГодМесяцДень
|...


ИЛИ как вариант (конечно хуже 1.)
2. в переменной Карта уже есть поле ЭтоГруппа, анализируйте его, когда вы через Ссылка.ЭтоГруппа обращаетесь к нему, происходит повторная загрука всего элемента справочника в память с сервера.
правильно (было бы) Если НЕ Карта.ЭтоГруппа Тогда

3. так как у вас уже могут быть элементы у которых НачалоДействия  = ГодМесяцДень, усложните условие что бы не изменять элементы у которых даты совпадают

Если Карта.ЭтоГруппа или Карта.НачалоДействия  = ГодМесяцДень Тогда
Продолжить;
КоенцЕсли;


вот как бы выглядела ваша программа в оптимизированом виде


    //берём объект из РС
    лкЗапрос = Новый Запрос;
    лкЗапрос.Текст = "
        |Выбрать //первые 50
        |    Ссылка
        |//    Наименование, так как все равно будет получать объект, то эти поля можно не получать в запросе
        |//    НачалоДействия
        |Из
        |    Справочник.РесурсныеСпецификации Спр
        |Где
        |    Не Спр.ЭтоГруппа
        |и   Спр.НачалоДействия <> &ГодМесяцДень //универсальнее использовать параметр
        |//и    Не Спр.ПометкаУдаления //!!! надо анализировать пометку удаления?
        |";
    ГодМесяцДень=Дата(2015,2,1);
    лкЗапрос.УстановитьПараметр("ГодМесяцДень",ГодМесяцДень);
   
    лкРезультат = лкЗапрос.Выполнить().Выбрать();
   
    //пробегаемся по всем обектам РС
    лкСчетчик = 0;
    Пока лкРезультат.Следующий() Цикл

        //если длинный цикл, полезно вставлять эту процедуру для прерывания обработки
        ОбработкаПрерыванияПользователя();

        //с помощью процедуры Состояние полезно выводить, хотя бы счетчик количества обработанных зписей, можно выодить % и т.д.
        лкСчетчик = лкСчетчик + 1;
        Состояние("Обработано: " + лкСчетчик );

        лкКарта = лкРезультат.Ссылка.ПолучитьОбъект();
        сообщить("РС = " + лкКарта.Наименование);           
        Сообщить("1 = " + лкКарта.НачалоДействия);
        лкКарта .НачалоДействия=ГодМесяцДень;
        Попытка
            //иногда при записи могут возникать ошибки
            лкКарта.Записать();
            Сообщить("2 = " + лкКарта.НачалоДействия);
        Исключение
    лкОшибка = ОписаниеОшибки();
        Сообщить(лкОшибка);
        КонецПопытки;
               
    КонецЦикла;



примерно так, могут быть опечатки, протестируйте
если помогло нажмите: Спасибо!

Рексарыч

MuI_I_Ika, спасибо за наводку по учебнику.

LexaK, премного благодарен. Не ожидал такого подробного анализа моего кода :zebzdr:. Приятно удивлён.

vitasw

Цитата: LexaK от 12 мая 2015, 13:12на диске ИТС есть хороший раздел по оптимальному...

Позволю себе чуть-чуть оптимизировать оптимизированное.
Цитата: LexaK от 12 мая 2015, 13:12ИЛИ как вариант (конечно хуже 1.)
согласен, поэтому предлагаю использовать в(&Параметр)

Всякие операторы: Состояние(), Сообщить() - нужно относится очень осторожно. С точки зрения платформы - это довольно затратные операции.

LexaK

vitasw, как это использовать? вернее зачем?
Цитировать
согласен, поэтому предлагаю использовать в(&Параметр)

автору надо поменять дату, достаточно по <> (не равно) выбрать только нужные элементы справочника и изменить только их.

Рексарыч,
Если ответ помог, не забываем давить кнопку спасибо? B)
если помогло нажмите: Спасибо!

vitasw

Моя оптимизация без привязки к исходной задаче. В общем случае "или" хорошо заменяется на "в"

LexaK

Цитата: vitasw от 12 мая 2015, 18:14
Моя оптимизация без привязки к исходной задаче. В общем случае "или" хорошо заменяется на "в"

а где вы ИЛИ увидели? в запросе стоит И !

    |...
    |Где
    |    Не Спр.ЭтоГруппа
    |И   Спр.НачалоДействия <> &ГодМесяцДень //универсальнее использовать параметр
    |...
если помогло нажмите: Спасибо!

vitasw

Все, ОК, не заморачивайтесь, нет там никаких "или", вы все насоветовали правильно.

Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск