Вход | Регистрация
    1  2   
1С:Предприятие :: 1С:Предприятие 8 общая

Почему в замере производительности дольше всего выполняется элементарная операция?

Почему в замере производительности дольше всего выполняется элементарная операция?
Я
   anchar007
 
13.05.21 - 13:34
Оптимизирую самописную внешнюю обработку. Она на основании огромного количества документов за определенный период создаёт новые документы.
В примере на скрине мы создаём новые документы на основании 21000 поступлений и 26000 реализаций, поэтому в некоторые строки мы попадаем по 47000 раз.
Скрин: https://ibb.co/8MY5DN3
Почему замер производительности показывает, что элементарная операция сравнения "Если Валюта.Код = "643" Тогда" выполняется в разы дольше, чем например какие-нибудь сложные операции типа запросов, которые вызываются примерно такое же количество раз?
Запускал замер производительности уже не один раз и всегда сравнение со строкой самое длительное.
   Lama12
 
1 - 13.05.21 - 13:36
(0) У "Валюта" тип, поди СправочникСсылка.Валюты?
   polosov
 
2 - 13.05.21 - 13:37
(1) Очевидно, что да.
   H A D G E H O G s
 
3 - 13.05.21 - 13:41
(0) 47000 обращений к субд потому что.
   azernot
 
4 - 13.05.21 - 13:42
(0) Уж сколько раз твердили миру, что получение значения реквизита через точку от ссылки - зло. По сути в момент обращения через точку, из БД получается весь объект.
   ManyakRus
 
5 - 13.05.21 - 13:43
Так нельзя сравнивать. Надо писать:
Если Валюта = ВалютаРуб Тогда
   Молодец();
КонецЕсли
   PR
 
6 - 13.05.21 - 13:44
(0) А что по-твоему делает элементарная операция Если Валюта.Код = "643"?
Понаберут по объявлению
   PR
 
7 - 13.05.21 - 13:46
Там еще за 250 строчку по ходу нужно морду набить
   ДенисЧ
 
8 - 13.05.21 - 13:47
(3) А как же внутреннее кеширование от 1с?
   mistеr
 
9 - 13.05.21 - 13:47
(1) И в строке 250 небось, НайтиПокоду() :)
   PR
 
10 - 13.05.21 - 13:47
И не удивлюсь, если окажется, что что-то с валютой можно было сделать уже в самом запросе, фильтр, группировку, разные значения полей, поле ЭтоРубль...
   azernot
 
11 - 13.05.21 - 13:47
(7) +100

Там видимо поиск по коду или по наименованию.. Внутри цикла, 47 тыс раз поиск одного и того же элемента.
   PR
 
12 - 13.05.21 - 13:48
(8) Кеширование чего, разных валют во всех местах, которые проверяет ТС?
   H A D G E H O G s
 
13 - 13.05.21 - 13:48
(8) 1с все равно проверяет, не изменился ли обьект, запрашивая version
   mistеr
 
14 - 13.05.21 - 13:49
(8) Код работает так долго, что кэш устаревает :)
   PR
 
15 - 13.05.21 - 13:50
А кто сказал, что выше строчкой нет такого?
Валюта = Выборка.Валюта;
   RomanYS
 
16 - 13.05.21 - 13:52
(14) да ладно. Вроде секунд 20 должен жить. По идее чтений десять по идеее должно быть реально у ТСа
(13) Вот это интересно. Спасибо.
   mistеr
 
17 - 13.05.21 - 13:53
(13) Не каждый раз же.
   Kesim
 
18 - 13.05.21 - 13:55
(0) из запроса получай сразу поле "ВалютаЕстьРубль"
   pechkin
 
19 - 13.05.21 - 13:56
а что 1с уже не кэширует получение через точку?
   pechkin
 
20 - 13.05.21 - 13:58
ну и разве быстрее будет
Валюта = Справочники.Валюты.НайтиПоКоду
или
Валюта = Константы.Валюта.Получить()
   azernot
 
21 - 13.05.21 - 13:58
(19) Очевидно, что значение переменной "Валюта" меняется в цикле.
   PR
 
22 - 13.05.21 - 13:58
(19) Еще один
Что она должна кешировать?
   pechkin
 
23 - 13.05.21 - 13:59
(22) всегда кэшировала (раньше по крайней мере)
   PR
 
24 - 13.05.21 - 13:59
(20) Ты бредишь
Соберись, тряпка и прочти ветку еще раз
   anchar007
 
25 - 13.05.21 - 14:00
(5) Попробовал изменить сравнение, чтобы сравнивать ссылки:
1) Обе переменные теперь ссылочного типа: https://ibb.co/72QTj9f
2) сделал новый замер, который показывает, что это всё равно самая длительная операция: https://ibb.co/MhkqcYb
   H A D G E H O G s
 
26 - 13.05.21 - 14:00
(20) (22) Вотс! Я думал, вы один и тот же человек...
   PR
 
27 - 13.05.21 - 14:00
(23) У ТС охрениард разных валют в цикле
Что именно 1С должна кешировать?
   mistеr
 
28 - 13.05.21 - 14:00
(22) Объекты ссылочных типов.
   pechkin
 
29 - 13.05.21 - 14:00
(24) а как ты еще валюту руб найдешь?
   PR
 
30 - 13.05.21 - 14:01
(29) Ты же сейчас шутишь?
Я ее, блеать, один раз вне цикла нахожу
 
 
   PR
 
31 - 13.05.21 - 14:01
(28) И? Продолжай
   RomanYS
 
32 - 13.05.21 - 14:01
(21) Думаешь там 40тыс разных валют?
   mistеr
 
33 - 13.05.21 - 14:01
(25) Код уже показывай.
   pechkin
 
34 - 13.05.21 - 14:01
(27) иди почитай про кэширование вначале, а потом уже приходи какахами кидаться
   PR
 
35 - 13.05.21 - 14:02
(25) Тебе сказали же, сделай поле ЭтоРубли в запросе
   PR
 
36 - 13.05.21 - 14:03
(34) Упс. С тобой все понятно. Вопросов больше не имею.
   polosov
 
37 - 13.05.21 - 14:03
   PR
 
38 - 13.05.21 - 14:04
(37) И че и че?
   polosov
 
39 - 13.05.21 - 14:05
(38) "Соответственно, при многократном обращении к одним и тем же данным будет выполняться многократное считывание. Этого можно избежать, обращаясь к свойствам ссылки. В этом случае используется кэширование объектов и в определенном интервале времени при повторном обращении к данным объекта не будет выполняться повторное считывание. "
   azernot
 
40 - 13.05.21 - 14:05
(32) Думаю валют там не 40 тыс, но они могут быть разные. Значение переменной "Валюта" заменяется в цикле новым значением, например, из выборки запроса. А значит кэш очищается.

Впрочем, у ТС теперь в (25) "Обе переменные теперь ссылочного типа, но это всё равно самая длительная операция."
И вот это уже непонятно.
   Kesim
 
41 - 13.05.21 - 14:06
(0) и желательно ВалютуРубли определить до цикла в котором запрос создается
   H A D G E H O G s
 
42 - 13.05.21 - 14:06
(25) Ты где то ошибся. Или внешнюю обработку не сохранил, или она закешировалась. Ненормален такой результат.
   mistеr
 
43 - 13.05.21 - 14:08
(38) Первый раз слышишь про объектный кэш?
   RomanYS
 
44 - 13.05.21 - 14:09
(40) >> А значит кэш очищается.
Вот это я так понимаю теперь очень спорный вопрос. Часть людей считают (я в том числе), что данные кэшируются по ссылке и не умирают в кэше при обновлении переменной. Вторая часть (минимум ты и PR) считают что кэш живёт и умирает вместе с переменной.
   mistеr
 
45 - 13.05.21 - 14:09
(40) Значение переменной замещается, а кэш остается в памяти. Если объект не менялся.
   anchar007
 
46 - 13.05.21 - 14:10
Вот весь код:

Функция ПересчитатьВалютнуюСумму(ВалютнаяСумма, Валюта, Дата)
    
    Если Валюта = ВалютаРуб Тогда
        
        Возврат ВалютнаяСумма;
        
    Иначе
        
        
        Возврат ПересчетСуммыПоКурсу(ВалютнаяСумма, Валюта, Дата);
        
    КонецЕсли;
    
КонецФункции
   mistеr
 
47 - 13.05.21 - 14:10
Этот кэш нужен именно для таких случаев. Обращение к часто используемым объектам из разных мест кода, в разных переменных.
   polosov
 
48 - 13.05.21 - 14:10
(44) Из (37)
"Разумеется, если необходимо многократно обращаться к одному и тому же полю в пределах одного и того же алгоритма, то эффективнее считать данные, запомнить их в переменную и обращаться к уже считанным данным. Но получение данных через ссылку может выдавать ранее считанные данные, даже если они были считаны в другом вызове встроенного языка, так как кэширование выполняется в рамках всей клиентской сессии."
   PR
 
49 - 13.05.21 - 14:10
(39) А где ты увидел одни и те же данные? Валюта же меняется в цикле
   H A D G E H O G s
 
50 - 13.05.21 - 14:10
На самом деле, PR тут поднял интересную тему. Которую Печкин не может вкурить.

Запрос.Текст=
"Выбрать
Номенклатура.Ссылка как Ссылка1,
Номенклатура.Ссылка как Ссылка2
Из...."

Выборка=Запрос.Выполнить().Выбрать();
Выборка.Следующий();

Ссылка1=Выборка.Ссылка1;
Ссылка2=Выборка.Ссылка2;
Наименование1=Ссылка1.Наименование;
// Будет ли тут использоваться кеш?

Наименование2=Ссылка2.Наименование;
   RomanYS
 
51 - 13.05.21 - 14:12
(50) я от тебя ответа на (44) ожидал, а для тебя это тоже интересная тема))
   mistеr
 
52 - 13.05.21 - 14:12
(50) Везде будет.
   H A D G E H O G s
 
53 - 13.05.21 - 14:12
(47) "в разных переменных."

Инфа - 100% ?
   PR
 
54 - 13.05.21 - 14:12
(40) Это непонятно, да
   mistеr
 
55 - 13.05.21 - 14:13
(49) Через N итераций валюта повторяется.
   H A D G E H O G s
 
56 - 13.05.21 - 14:13
Ща проверим
   azernot
 
57 - 13.05.21 - 14:13
(45) (44) Проведите простой эксперимент.
Сформируйте запрос 40 тыс раз получающий пару валют из справочника, упорядочив по ссылке.

И далее, замерьте 2 варианта кода
Пока Выборка.Следующий() Цикл
 Валюта = Выборка.Валюта;
 Сообщить(Валюта.Код);
КонецЦикла;


Пока Выборка.Следующий() Цикл
 Если НЕ Валюта = Выборка.Валюта ТОгда
   Валюта = Выборка.Валюта;
 КонецЕсли;
 Сообщить(Валюта.Код);
КонецЦикла;
   polosov
 
58 - 13.05.21 - 14:14
(50) Да, будет.
В https://its.1c.ru/db/metod8dev/content/2717/hdoc есть про правильное получение представления.
   RomanYS
 
59 - 13.05.21 - 14:14
(56) и про version дай пруф, пожалуйста, если есть под рукой
   mistеr
 
60 - 13.05.21 - 14:14
(57) Сам не хочешь? :)
 
 
   PR
 
61 - 13.05.21 - 14:14
(46) Это не может быть всем кодом, потому что ты обращаешься к Валюта, которой нет ни в параметрах ни присвоения раньше
Это же, надеюсь, не реквизит формы?
   mistеr
 
62 - 13.05.21 - 14:15
   PR
 
63 - 13.05.21 - 14:16
(50) Хороший вопрос
И проверяется легко
   RomanYS
 
64 - 13.05.21 - 14:16
(62) что-то не то.
   PR
 
65 - 13.05.21 - 14:17
(55) Не уверен, что если ты в переменную записал валюту, которая уже раньше где-то как-то закешировалась, то реквизиты теперь возьмутся из кеша
Опять же, это легко проверяется
   mistеr
 
66 - 13.05.21 - 14:18
(64) То самое.

"Если обращаться через ссылки к свойствам одного и того же объекта базы данных, то считывание данных будет происходить только при первом обращении, а так же после того как система выгрузит этот объект из кэша. Данные объекта удерживаются в кэше около 20 минут, но после интервала в 20 секунд при очередном обращении будет выполняться проверка того, что объект в базе данных не менялся, и, при необходимости, выполняется обновление данных в кэше. Если объект записывается в данной сессии, то он сразу обновляется в кэше."
   H A D G E H O G s
 
67 - 13.05.21 - 14:18
Да, кешируется, несмотря на разные переменные.
   RomanYS
 
68 - 13.05.21 - 14:20
(67) Ну хоть тут интуиция (и не 1С) не подвела))
   PR
 
69 - 13.05.21 - 14:20
Что-то ТС темнит
   PR
 
70 - 13.05.21 - 14:21
(67) А если валюты одинаковые, но взяты из разных мест, например из разных документов, то есть путь разный?
   H A D G E H O G s
 
71 - 13.05.21 - 14:21
Про повторное считывание - оно считывает Версию раз в 20 секунд. И получает весь пул реквизитов, по условию, отличному от версии:
   H A D G E H O G s
 
72 - 13.05.21 - 14:21
Запрос=Новый Запрос;
    Запрос.Текст=
    "ВЫБРАТЬ
    |    Справочник1.Ссылка КАК Ссылка1,
    |    Справочник1.Ссылка КАК Ссылка2
    |ИЗ
    |    Справочник.Справочник1 КАК Справочник1";
    Выборка=Запрос.Выполнить().Выбрать();
    Выборка.Следующий();
    
    Ссылка1=Выборка.Ссылка1;
    Ссылка2=Выборка.Ссылка2;
    Наименование1=Ссылка1.Наименование;
    Пока Истина Цикл
        Наименование2=Ссылка2.Наименование;
    КонецЦикла;
   RomanYS
 
73 - 13.05.21 - 14:21
(66) Спасибо. Я "верс", "vers" искал
   anchar007
 
74 - 13.05.21 - 14:22
(61) через ПЕРЕМ объявил переменную ВалютаРуб, записал в неё валюту один раз и потом в цикле к ней обращаюсь
   RomanYS
 
75 - 13.05.21 - 14:22
(70) кэш по ссылке, по фигу откуда тыее берешь
   H A D G E H O G s
 
76 - 13.05.21 - 14:23
   H A D G E H O G s
 
77 - 13.05.21 - 14:24
Подозреваю, что когда у сервера 1С занятая память подходит к 85% физической, картинка меняется.
   H A D G E H O G s
 
78 - 13.05.21 - 14:24
Сеансовые данные в такой период активно сбрасываются на диск, например.
   RomanYS
 
79 - 13.05.21 - 14:26
(76) Спасибо
   mistеr
 
80 - 13.05.21 - 14:27
Кстати, а транзакций в секретном коде ТС нет ли?
   anchar007
 
81 - 13.05.21 - 14:29
(80) нет, транзакций нет
   BIP1
 
82 - 13.05.21 - 14:36
(81) Покажите код, где вызывается ваша функция ПересчитатьВалютнуюСумму()
   RomanYS
 
83 - 13.05.21 - 14:41
(82) Ага. прикольно будет, если она с клиента контекстным серверным вызовом происходит) За то сразу всё станет на место, даже замер в (25).
   azernot
 
84 - 13.05.21 - 14:42
Выше уже подтвердили, но и я отпишусь.
(60) Я проверил. Вы правы. Данные объекта кэшируются.
   Lama12
 
85 - 13.05.21 - 14:44
(74) Толстый клиент? Формы не управляемые?
   VladZ
 
86 - 13.05.21 - 14:45
(0) Потому что потому (с) Сами-знаете-кто.
   mistеr
 
87 - 13.05.21 - 14:45
(83) В замере (0) видно, что все на сервере.
   anchar007
 
88 - 13.05.21 - 14:54
(81) всё на сервере вызывается. Сначала запросом формирую таблицу документов, а потом итерируюсь по этой таблице и выполняю различные действия, в том числе пересчитываю сумму в рубли согласно курсу
(85) управляемые формы
   BIP1
 
89 - 13.05.21 - 15:04
Откуда в вашей функции берется значение переменной ВалютаРуб?
ВалютнаяСумма, Валюта, Дата - вы передали в качестве параметров функции. А ВалютаРуб - это что?


Функция ПересчитатьВалютнуюСумму(ВалютнаяСумма, Валюта, Дата)
    
    Если Валюта = ВалютаРуб Тогда
        
        Возврат ВалютнаяСумма;
        
    Иначе
        
        
        Возврат ПересчетСуммыПоКурсу(ВалютнаяСумма, Валюта, Дата);
        
    КонецЕсли;
    
КонецФункции
   Lama12
 
90 - 13.05.21 - 15:14
(89) Меня вот тоже смущает этот момент. Но в (74) сказано что объявил через Перем. Вопрос только, где это объявление и присвоение значения произведено?
   dmpl
 
91 - 13.05.21 - 15:14
(74) Тип переменной какой?
   Lama12
 
92 - 13.05.21 - 15:16
(91) Судя по (25) оба справочник ссылка. Но где в коде эти значения получены, неясно.
   Жан Пердежон
 
93 - 13.05.21 - 15:30
(25) у тебя это сравнение 23тыщи раз выполняется - раздели время на количество и будет < 0,0022 на одну операцию
   anchar007
 
94 - 13.05.21 - 15:35
Перем ВалютаРуб;
(92)


Процедура ЗаполнитьТаблицуУслуг(ТаблицаДок)

    ВалютаРуб = Справочники.Валюты.НайтиПоКоду("643");

    Для каждого строка из ТаблицаДок Цикл
                
        НоваяСтрокаУслуги = ТаблицаУслуг.Добавить();

        НоваяСтрокаДокументы.СуммаПоУслуге = (-1)*ПересчитатьВалютнуюСумму(строка.СуммаУслуги, 
                                                строка.Документ.ВалютаДокумента, 
                                                строка.Документ.Дата);
    КонецЦикла;
КонецПроцедуры;
   RomanYS
 
95 - 13.05.21 - 15:36
(94) строка.Документ.ВалютаДокумента - это ппц
   RomanYS
 
96 - 13.05.21 - 15:39
(87) строго говоря, видно что эта строка выполняется на сервере. Откуда вызвана функция мы не видим.
Но проверил, расходы на передачу контекста в отладке показываются в строке вызова функции (а не на её первую строку) - моё предположение в (83) не могло быть верным при таком замере
   anchar007
 
97 - 13.05.21 - 15:41
(93) но в любом случае сравнение двух переменных должно выполняться в разы быстрее, чем например запрос.
В строке 521 запрос вызывается 11826 раз (в 2 раза реже. чем сравнение двух переменных). А выполняется он в 7 раз быстрее.
В строке 267 я 23 тыс. раз ищу элементы справочника номенклатурные группы по наименованию. Очевидно, что процедура поиска по значению в разы медленнее, чем процедура сравнения двух ссылок. Но однако она тоже выполняется примерно в 7 раз быстрее.
   H A D G E H O G s
 
98 - 13.05.21 - 15:42
(97) Ты где то ошибся в замере.
   BIP1
 
99 - 13.05.21 - 15:43
(97) а теперь замените строку "строка.Документ.ВалютаДокумента" на "ВалютаДокумента", а переменной ВалютаДокумента присвойте значение ВалютаДокумента = строка.Документ.ВалютаДокумента чуть выше.
И запустить замер снова.
   Жан Пердежон
 
100 - 13.05.21 - 15:43
(94) всё равно говнокод)
  1  2   

Список тем форума
 
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.