Имя: Пароль:
1C
1С v8
помогите оптимизировать скорость кода
0 vde69
 
23.10.12
09:25
есть обработка где очень большое количество вызовов следующей процедуры, очень долго выполняются две простые строчки, не придумаю как оптимизировать...



Процедура ЗаписатьРеквизитыБлока (Блок, СтрокаДанных = Неопределено, ИзменяемыеРеквизиты = Неопределено) Экспорт
   ТребуетсяЗапись = Ложь;
   
   оБлок = Блок.ПолучитьОбъект();
   
   //
   // блок критичный по скорости, по этому жертвуем читабельностью
   //
   Если ТипЗнч(СтрокаДанных) = Тип("Строка") Тогда
       Для е = 0 по 255 Цикл
           Если оБлок.Данные.Количество() <= е Тогда оБлок.Данные.Добавить(); КонецЕсли;
           мСтрока = оБлок.Данные[е];
           _мЕ = е*32-1;
           Для е2 = 1 по 16 Цикл
               мЗначение = Сред(СтрокаДанных, _мЕ+е2*2, 2);
               Если мЗначение = "" Тогда мЗначение = "00";    КонецЕсли;
               // след. 2 строчки отьедают 22% времения
               мИмяКолонки = "Бин"+Строка(е2);
               Если мСтрока[мИмяКолонки] <> мЗначение Тогда мСтрока[мИмяКолонки] = мЗначение; ТребуетсяЗапись = Истина; КонецЕсли;
               
           КонецЦикла;
       КонецЦикла;              
   КонецЕсли;
   
   _мТипИзменяемыеРеквизиты = ТипЗнч(ИзменяемыеРеквизиты);
   Если    (_мТипИзменяемыеРеквизиты = Тип("Структура")) ИЛИ (_мТипИзменяемыеРеквизиты = Тип("Соответствие")) Тогда
       
       Для Каждого ИзменяемаяЗапись из ИзменяемыеРеквизиты Цикл
           
           Если оБлок[ИзменяемаяЗапись.Ключ] <> ИзменяемаяЗапись.Значение Тогда
               оБлок[ИзменяемаяЗапись.Ключ] = ИзменяемаяЗапись.Значение;
               ТребуетсяЗапись = Истина;
           КонецЕсли;
       
       КонецЦикла;
   КонецЕсли;
   
   Если ТребуетсяЗапись Тогда
       оБлок.Записать();
   КонецЕсли;
КонецПроцедуры
1 H A D G E H O G s
 
23.10.12
09:26
Ужас
2 H A D G E H O G s
 
23.10.12
09:27
мИмяКолонки = "Бин"+Строка(е2);

не прибавляй строку в цикле
3 H A D G E H O G s
 
23.10.12
09:29
Короче, нуего нафиг, разбираться в таком уежищном коде.
4 vde69
 
23.10.12
09:31
(2) строка ТЧ не поддерживает обращение по индексу, только по имени, по этому приходится так...

смысл процедуры
1. гарантировано создать ТЧ на 255 строк и 16 колонок и заполнить ее по 2 символа из строки "СтрокаДанных", если строка короче - добить "00"
5 vmv
 
23.10.12
09:32
Если оБлок.Данные.Количество() <= е Тогда оБлок.Данные.Добавить(); КонецЕсли;

эта строка дико уродская
6 vde69
 
23.10.12
09:32
(1) кстати чем конкретно код не нравися? кроме того что операторы в одну строку
7 mehfk
 
23.10.12
09:32
Если мСтрока[мИмяКолонки] <> мЗначение Тогда мСтрока[мИмяКолонки] = мЗначение; ТребуетсяЗапись = Истина; КонецЕсли;

Смысл проверять на неравенство в этом?
>ТребуетсяЗапись = Истина;
8 Maxus43
 
23.10.12
09:33
(5) да всё такое там)
(0) Может логику пересмотреть? пихать данные в хранилище значений например, там ТЗ хранить, иль что лучше для задачи подойдёт...
9 vmv
 
23.10.12
09:33
(4) создай контейнер Тч 255*16 перед заполнением в цикле и не врим мне про индексы
10 Jstunner
 
23.10.12
09:34
нет смысла писать такой ущербный код ради быстродействия, он все равно конвертится в байткод
11 butterbean
 
23.10.12
09:35
(0) делай все это в ТЗ и загружай ее потом в ТЧ, должно быть гораздо быстрее
12 Goggy
 
23.10.12
09:35
(4) не ври.
И пересмотри вообще логику этого блока.
13 vvp91
 
23.10.12
09:35
(4) Перепиши все на массивах или соответствиях, а уже их наборы загружай в табчасть или табзначений.
Остальные структуры существенно медленней в части обращений через точку или через индекс.
14 H A D G E H O G s
 
23.10.12
09:35
(6) Этим самым и всякими _мЕ, е2
15 H A D G E H O G s
 
23.10.12
09:36
(10) Пффф.
16 vde69
 
23.10.12
09:38
(7) для того что-бы избежать записи обьекта если данные не изменены, имено по этому изначально не стал использовать промежуточную ТЗ, по сколько по скорости - не дает выигрыша.
17 vmv
 
23.10.12
09:38
"_" использую только в наименованиях переменных/объектов которые интегруються с 1С из других систем лдап, чужеродные среды, винапи и пр.

во всех остальных тулить 1Совским идентификаторам "_" считаю признаком матерого извращенца и требую казни
18 vde69
 
23.10.12
09:44
хорошо, как ускорить строку? Простой вопрос :)

мИмяКолонки = "Бин"+Строка(е2);
19 Jstunner
 
23.10.12
09:45
(18) сделать готовый массив строк
20 H A D G E H O G s
 
23.10.12
09:47
(19) +500

Вынести ее за циклы
21 H A D G E H O G s
 
23.10.12
09:48
Все равно у тебя ее 16 вариантов будет
Бин1
Ьин2
...
Бин16
22 1Страх
 
23.10.12
09:48
а если в самом начале до циклов сделать изврат типа:

МассивКолонок = Новый Массив;
Для й=1 по 16 цикл
 МассивКолонок.Добавить("Бин"+Строка(е2));
КонецЦикла;

а потом в цикле уже:

мИмяКолонки = МассивКолонок[е2-1];
23 H A D G E H O G s
 
23.10.12
09:49
А вообще бида, что 1С не сделала индексных строк, типа

strParam[12]:='S';
24 Stepa86
 
23.10.12
09:50
(18) заполненное соответствие или массив попробуй и мИмяКолонки = бины[е2]
25 vde69
 
23.10.12
09:55
(19) сделал, помогло, теперь остался кусочек


Если мСтрока[мИмяКолонки] <> мЗначение Тогда
 мСтрока[мИмяКолонки] = мЗначение;
 ТребуетсяЗапись = Истина;
КонецЕсли;
26 Stepa86
 
23.10.12
09:57
(25) в мСтрока[мИмяКолонки] тип какой?
27 vde69
 
23.10.12
09:57
(26) Строка табличной части
28 vde69
 
23.10.12
09:58
(27) вру

мСтрока - Строка табличной части
мСтрока[мИмяКолонки]  - Строка[2]
29 1Страх
 
23.10.12
10:02
в качестве флуда, а так:

Если Не (мСтрока[мИмяКолонки] = мЗначение) Тогда
30 vde69
 
23.10.12
10:03
(29) кстати да совсем забыл про это
31 Stepa86
 
23.10.12
10:03
(28) на что конкретно тратиться время? на получение значения из строки, на сравнение или на присвоение?
32 vmv
 
23.10.12
10:04
тока скобки там не нужны, да на такую хрень я потратил 10 минут, любуясь копошением профи в г-коде
33 1Страх
 
23.10.12
10:04
мТребуетсяЗапись = Не(мСтрока[мИмяКолонки] = мЗначение);
Если мТребуетсяЗапись Тогда
 мСтрока[мИмяКолонки] = мЗначение;  
КонецЕсли;
ТребуетсяЗапись = ТребуетсяЗапись или мТребуетсяЗапись;
34 Simod
 
23.10.12
10:05
(25) После того как нашел первое неравенство прерывай цикл и начинай заново с тех позиций где остановился без всяких проверок просто "забивая" данные. Записывать все равно придется.

Ну, это если совсем ни хочется все переписывать.
35 1Страх
 
23.10.12
10:05
не проще ли, раз уж надо оптимизировать, вынести это в ВК?
36 vmv
 
23.10.12
10:07
(35) тгда уж на асме навоять - ваще пипец будет
37 vde69
 
23.10.12
10:13
пока вроде нашел приемлемый вариант:

               Если ТребуетсяЗапись Тогда
                   мСтрока[мИмяКолонки] = мЗначение;
               ИначеЕсли не (мСтрока[мИмяКолонки] = мЗначение) Тогда
                   мСтрока[мИмяКолонки] = мЗначение; ТребуетсяЗапись = Истина;
               КонецЕсли;
38 vde69
 
23.10.12
10:25
новая задачка, удаляем элементы справочника (все по владельцу)
долго идет само удаление, справочник с иерархией элементов



   КоличествоБлоков = 200;
   
   Запрос = Новый Запрос;
   Запрос.УстановитьПараметр("Владелец", Файл);
   
   Запрос.Текст =
   "ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ " + КоличествоБлоков  + "
   |    Блоки.Ссылка
   |ИЗ
   |    Справочник.Блоки КАК Блоки
   |ГДЕ
   |    Блоки.Владелец = &Владелец
   |    И Блоки.Родитель.Родитель ЕСТЬ NULL ";
   
   
   Выборка = Запрос.Выполнить().Выбрать();
   
   НачатьТранзакцию();
       Пока Выборка.Следующий() Цикл
           Выборка.Ссылка.ПолучитьОбъект().Удалить();
       КонецЦикла;
   ЗафиксироватьТранзакцию();
39 pumbaEO
 
23.10.12
10:29
(38) Зачем нужна иерархия?
У тебя вроде только 2-х уровневая получается структура или может быть n уровеневая?
40 vde69
 
23.10.12
10:30
(39) сейчас 4 уровня, но в преспективе может и более быть
Компьютер — устройство, разработанное для ускорения и автоматизации человеческих ошибок.