Имя: Пароль:
1C
1С v8
Какая конструкция быстрее работает
0 iwannafly90
 
22.08.14
09:31
Всем привет. Интересует один вопрос - какая конструкция цикла быстрее "для каждого... из... цикл" или "для... по... цикл"?
1 ДенисЧ
 
22.08.14
09:32
если интересует - то почему не написать тест и сообщить об эом??
2 StaticUnsafe
 
22.08.14
09:32
(0) для по цикл
3 чувак
 
22.08.14
09:32
замер производительности отменили уже?
4 patria0muerte
 
22.08.14
09:33
(0) Спроси еще, что быстрее, НЕ = или <>
5 iwannafly90
 
22.08.14
09:34
(1)(3) Просто любопытно. Разбираю чужой код и тут использованы разные конструкции циклов. Замерять производительность пока времени нет, поэтому и спросил
6 hhhh
 
22.08.14
09:36
(2) Как раз наоборот.
7 чувак
 
22.08.14
09:37
(5) "Замерять производительность пока времени нет"
Займет пару минут
8 iwannafly90
 
22.08.14
09:37
(4) при чем тут операция сравнения? по циклам было интересно, просто если нет разницы, то не буду править чужой код, а если есть, то буду
9 iwannafly90
 
22.08.14
09:39
(7) да знаю, там просто модуль большой, написан через одно место и комментариев нет, поэтому пока хочу хотя бы понять, что там да как. Потому и написал здесь, думал, пока буду разбирать этот код, тут ответят
10 ДенисЧ
 
22.08.14
09:39
(9) прошло 8 минут.
За это время уже можно было бы написать тест и проверить.
11 ДенисЧ
 
22.08.14
09:40
(8) принципиальной разницы нет. Так что можешь спокойно идти з апивом.
12 floody
 
22.08.14
09:41
даже если есть небольшая разница, думаю это не принципиально. важнее удобство и наглядность использования того или иного цикла.
13 Фокусник
 
22.08.14
09:44
(8) "то не буду править чужой код, а если есть, то буду"

ИМХО, ТОЛЬКО из-за производительности править эти конструкции НЕ нужно, это тот случай, когда "работает - не трожь!" :)
14 Defender aka LINN
 
22.08.14
09:44
Угу. Вот придет такой одинэснег, оптимизирует запрос путем замены "Для ... По ..." на "Для Каждого" и уйдет довольный. Ускорил работу цикла, в котором запрос движений по регистраторам без отборов, на целых 0,25с.
15 StaticUnsafe
 
22.08.14
09:45
(6) дядь, вообще-то циклы вида for each появились гораздо позже циклов с итераторами. в том же с++ (например), и являются, по сути ,обёрткой над коллекцией, т.о. цикл вида "для каждого из" как минимум перед выполнением вычисляет значения итератора, тогда как в "для по" они указываются явно.
16 H A D G E H O G s
 
22.08.14
09:46
(14) 0.25 секунд работы запроса - это уже кандидат на поиск проблем.
17 Defender aka LINN
 
22.08.14
09:52
(16) Кофе не пил с утра, что ли? Я намекаю, что аффтар не с той стороны к оптимизации подходит. Ему пофигу, сколько запросы выполняются.
18 hhhh
 
22.08.14
10:00
(15) зато там в по может быть офигенная операция сравнения, которая может одна дольше чем 10 циклов выполняться. И в для... по... цикл именно такие операции в основном.
19 iwannafly90
 
22.08.14
10:01
(17) Мне не пофиг на запросы, запрос тут в принципе не при чем. Там перебираются строки массивов. Двух разных массивов разными циклами
20 hhhh
 
22.08.14
10:02
(18)+ а нет, это я с циклом пока спутал.
21 zulu_mix
 
22.08.14
10:04
(4) что быстрее:

cmp ax,bx
je short

или

xor ax,bx
jz short
22 ViSo76
 
22.08.14
10:10
xor ax,bx
jz short

быстрее
23 ViSo76
 
22.08.14
10:11
Хотя там идёт сброс/установка битов, а выше проверка, может и наоборот
24 hhhh
 
22.08.14
10:16
не знаю как реализовано в платформе, но по логике

Для Каждого ТекСтрока Из ТЗ Цикл
КонецЦикла;

должно быть быстрее

Для ии = 0 ПО ТЗ.Количество() - 1 Цикл
   ТекСтрока = ТЗ[ии];
КонецЦикла;
25 zulu_mix
 
22.08.14
10:17
(23) проверка дольше. так что конструкция с НЕ будет быстрее
26 fmrlex
 
22.08.14
10:19
(21) Зависит от проца.
27 Йохохо
 
22.08.14
10:23
(0) во втором цикле элементы будут получаться по индексу кодом, а не платформой
28 vhl
 
22.08.14
10:29
(0) Преждевременная оптимизация - корень всех зол (с).
Не туда копаешь, в общем. Вынеси запрос вообще из цикла.
29 ViSo76
 
22.08.14
10:34
(24) Сомнительно что быстрее, учитывая что строка

ТекСтрока = ТЗ[ии];

всё равно выгребается, при том что идёт доступ по индексу, а строки ( объекты ) скорее всего ищутся по цепочке, а не в массиве.

PS: По моему с циклом это не то на что стоило бы обращать внимание.
30 Bigbro
 
22.08.14
10:47
(21) на 486х процессорах быстрее 2й вариант.
31 anatoly
 
22.08.14
10:50
(30) xor на _всех_ процессорах быстрее, даже на Z80 ))
32 Bigbro
 
22.08.14
10:51
31 от Z80 я диаграммы времени исполнения инструкций по тактам не видел
а от 486 видел
33 hhhh
 
22.08.14
10:53
(29) нет, все-таки быстрее. Провел тест. на ТЗ в 10000 строк

получается: 1-й вариант из (24)

Для Каждого ТекСтрока Из ТЗ Цикл     0.038
КонецЦикла;                          0,021

второй вариант

Для ии = 0 ПО ТЗ.Количество() - 1 Цикл   0,017
ТекСтрока = ТЗ[ии];                      0,037
КонецЦикла;                              0,020

то есть первый вариант в полтора раза быстрее

замер производился на УФ.
34 ViSo76
 
22.08.14
10:57
(30) Да и оптимизации не будет. Всё будет выполняться в одной "трубе", так как проц будет ждать переход, а предпроцессор возможно ошибётся и в кэш кода загрузит неверные данные ( процессор не занимается переходами ). Из-за этого весь камень встанет колом в ожидании нужных данных, если конечно такие варианты уже не учли.
35 ViSo76
 
22.08.14
11:08
(33) Так я и имел ввиду что for each быстрее. Представим себе как исполняется код:

Есть цепочка связанных объектов Строка ТЗ -> Строка ТЗ -> Строка ТЗ. Объект ТаблицаЗначений ссылается на первую строку, а 11-я строка на последующую и т.д. ( скорее всего так это и реализовано ).

В случае с for each берётся первая строка, в этом объекте есть уже ссылка на следующий в памяти. То есть не нужно искать. Как же будет действовать обычный for:

Выбирает следующую итерацию быстро, но поиск по списку нужного объекта отнимает много времени.
36 ДенисЧ
 
22.08.14
11:10
(35) Я надеюсь, что ТЗ таки реализовано через массив, а не список...
37 ViSo76
 
22.08.14
11:11
(36) А ты думаешь что массив это не список?
38 ДенисЧ
 
22.08.14
11:12
(37) уверен.
39 HeroShima
 
22.08.14
11:13
(15) Лисперам и фортщикам это расскажи.
40 ViSo76
 
22.08.14
11:13
Хорошо как в памяти устроен массив?
41 ДенисЧ
 
22.08.14
11:13
(40) кусок памяти. Цельный. По которому можно смещением от начального адреса перейти. А не по ссылкам
42 ViSo76
 
22.08.14
11:14
А когда не хватает выделенного блока?
43 ДенисЧ
 
22.08.14
11:15
(42) марш читать основы. И не отвлекай дяденек от дела.
44 ViSo76
 
22.08.14
11:16
(41) Единственное как можно оптимизировать массив это выделять страницы ( по допустим 10-50 записей ) но это жрёт память и я не уверен что так устроен массив.
45 ДенисЧ
 
22.08.14
11:16
(44) ты не уверен, а я знаю, как это сделано в нормальных языках.
Вот и вся разница между нами.
46 ViSo76
 
22.08.14
11:18
А я не уверен что 1С применила такую схему
47 ДенисЧ
 
22.08.14
11:19
(46) факты есть? Нет. Свободен.
48 ViSo76
 
22.08.14
11:20
(47) А у тебя есть? Нет. Свободен.
49 HeroShima
 
22.08.14
11:24
(0) Зависит от ситуации.
50 vde69
 
22.08.14
11:26
как можно сравнивать желтое с теплым????

цикл имеет смысл, только если он чего-то делает...

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

"для... по... цикл" - цикл интератора, если интератор используется непосредственно в условии, то он предпочтительнее, пример:
для е=1 по 100 цикл
  если е = А или е = Б Тогда продолжить;
51 ASU_Diamond
 
22.08.14
11:28
Провел замеры:
Для каждого лСтр Из лТабл Цикл    0,286189

лКоличество=лТабл.Количество();    1    0,000014
Для А=0 По лКоличество-1 Цикл    0,107694
лСтр=лТабл[А];    0,267270

Выводы за вами
52 ViSo76
 
22.08.14
11:29
(50) Это всё понятно. Применение конструкции зависит от условий. Здесь случай если нужно тупо перебрать коллекцию и с ней произвести какие-то действия.
53 vde69
 
22.08.14
11:30
(51) о чем я и говорил :)
54 ASU_Diamond
 
22.08.14
11:31
(+51) извините что так подло оборвал вашу дискуссию :)
55 ViSo76
 
22.08.14
11:33
(47) Судя по всему товаришь ДенисЧ не в теме. Если бы ТЗ по массиву работало то цифры for each и for были бы примерно одинаковыми.
56 ptiz
 
22.08.14
11:34
Помню, чтобы не тратить время команды цикл, внутри цикла вставлял 10 команд обработки элементов подряд, чтобы один перебор цикла приходился на 10 команд, а не на одну.
(извращаться так приходилось на asm-е, там было критично)

Только "хвост" надо будет отдельно обработать, чтобы за границу массива не вылезти.
57 HeroShima
 
22.08.14
11:36
(56) Сейчас адекватные компиляторы сами так оптимизируют.
58 ViSo76
 
22.08.14
11:36
в asm чтобы ускориться нужно соседние обрабатывать строки, так как из памяти в кэш считывается блоками. Чтобы реально оптимизированный код писать там нужно не просто циклами баловаться, а понимать как распаралеливается код при исполнении.
59 ptiz
 
22.08.14
11:40
(58) на БК-0010 не было распараллеливания, мне надо было экран одним цветом закрасить :)
60 ViSo76
 
22.08.14
11:45
Мы ещё баловались на Радио 86 РК, затем на z80, XT, AT, PC
61 ViSo76
 
22.08.14
11:47
(59) C Pentium пошло 2 потока ( не путать с ядрами и гипертрейдингом )
62 Кирпич
 
22.08.14
11:55
(50) чо за "интератор"? итератор что ли? :))
63 HeroShima
 
22.08.14
11:57
>> Существует спор относительно того, какую ЭВМ можно считать первой суперскалярной. В иностранной литературе чаще всего указывается CDC 6600 (1964) разработанная Сеймуром Крэем. В СССР первой суперскалярной ЭВМ считался «Эльбрус», разработка которого велась в 1973—1979 годах в ИТМиВТ.
64 ViSo76
 
22.08.14
12:02
(63) Спасибо за историческую справку, я просто привёл с какого момента в x86 появилась возможность распалить код.
65 HeroShima
 
22.08.14
12:03
(64) Тогда с появления арифметического сопроцессора.
66 ViSo76
 
22.08.14
12:05
(65) Уговорил с появлением i386 SX
67 ViSo76
 
22.08.14
12:06
(66) Вру с i286 появился вроде бы, если мне память не изменяет.
68 HeroShima
 
22.08.14
12:07
>> Процессор Intel 8087 был выпущен в 1980 году, он стал первым математическим сопроцессором для линейки процессоров 8086 (x87)
69 ViSo76
 
22.08.14
12:09
(68) Да но процессор 8086 был на XT а там на сколько я знаю не было сопроцессора
70 HeroShima
 
22.08.14
12:13
(69) смотря какая модель
71 HeroShima
 
22.08.14
12:27
72 StaticUnsafe
 
22.08.14
12:54
(39) не считается. Лисп - функциональщина, и у них там своя атмосфера с самого начала, в отличие от процедурных и ООП языков.
73 supremum
 
22.08.14
12:59
(65) С чего бы это? Разве ЦП не ожидал завершения операции на сопроцессоре?
74 StaticUnsafe
 
22.08.14
13:03
(33) зачем ТекСтрока = ТЗ[ии] то? ТЗ[ии] и есть нужный элемент, к чему объявлять переменную
75 HeroShima
 
22.08.14
13:12
(72) >>Язык является функциональным, но начиная уже с ранних версий обладает также чертами императивности, к тому же, имея полноценные средства символьной обработки, позволяет реализовать объектно-ориентированность

(73) Не ожидал. Зачем, если у сопроцессора свои регистры, а операции обмена данными с центральным процессором сравнительно редки?
76 mehfk
 
22.08.14
13:18
(75) А чем по-вашему занимается 86 пока 87 что-то там считает?

TEST
    An input that is tested by the WAIT instruction.
    Commonly connected to the 8087 coprocessor.
77 supremum
 
22.08.14
13:19
(76) +1
78 HeroShima
 
22.08.14
13:20
Если память мне не совсем изменила, конкретно по i80287: для параллельного исполнения нужно было определённым образом чередовать определённые команды цпу с определёнными командами сопроцессора.
79 HeroShima
 
22.08.14
13:22
(76) ?
-Что-то там выполняет.
80 supremum
 
22.08.14
13:23
+(73) Нет, не так.

Процессор продолжает выполнять команды.
81 supremum
 
22.08.14
13:24
+(80) Команда FWAIT останавливает работу процессора до завершения вычислений на сопроцессоре.
82 HeroShima
 
22.08.14
13:48
83 mehfk
 
22.08.14
14:28
А как 86 без wait сможет узнать что 87 отработал и можно можно использовать результат?
84 oleg_prg
 
22.08.14
14:59
85 supremum
 
22.08.14
15:13
(83)
Вот не помню. Вроде после запуска выполнения команды сопроцессора должна генерироваться автоматом команда Wait. Кажись так.
86 Ndochp
 
22.08.14
15:20
(47) Вот тебе железобетонный факт из 1С
СП:
Массив.Добавить (Array.Add)
Массив (Array)
Добавить (Add)
Синтаксис:
Добавить(<Значение>)
Параметры:
<Значение> (необязательный)
Тип: Произвольный.
Добавляемое значение. Если не указан, то будет добавлено значение типа Неопределено.
Описание:
Добавляет элемент в конец массива.
Доступность:
Тонкий клиент, веб-клиент, сервер, толстый клиент, внешнее соединение.
Примечание:
При добавлении количество элементов массива увеличивается на 1.


Расскажи, как будет работать этот метод, если массив это единый блок памяти?
87 timurhv
 
22.08.14
15:22
(33) Таблица маленькая. Один раз количество строк нельзя разве посчитать и засунуть ее в переменную?
88 mehfk
 
22.08.14
18:16
(86) Более сильным аргументом (в пользу того, что массив в 1с это список) был бы отсыл к методам Вставить() и Удалить(), а метод Добавить() - это отсыл к динамическому массиву :)
Компьютер — устройство, разработанное для ускорения и автоматизации человеческих ошибок.