Форум программистов, компьютерный форум, киберфорум
Наши страницы
Basic
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
Formanter
12 / 12 / 2
Регистрация: 07.04.2010
Сообщений: 74
1

For-Next в разных BASIC: количество итераций внутри цикла уже не изменить

21.08.2012, 17:37. Просмотров 2368. Ответов 26
Метки нет (Все метки)

Изучал бейсик на ZX-Spectrum. Если кто не знает, это такая клавиатура, которая подключается к ТВ, а вместо дисковода используется кассетный/бабинный магнитофон.
Потом не мало посидел в QBasic под DOS.

Spectrum и QBasic при изменении значения max меняли количество повторов цикла.
Visual Basic
1
2
3
4
5
For i= min to max
что то делаем
If чего-то там случилось then max = max-1
еще что то делаем
Next i
Сегодня столкнулся интересной особенностью For-Next в VBA
Современному VBA нет дела до изменения значения параметра. Было сказано до max. Значит до max, и забудь что ты передумал и поменял значение max.
Пришлось использовать While, но это ж не по фен-шую, для простого перебора оптимален именно For-Next.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.08.2012, 17:37
Ответы с готовыми решениями:

Нужное количество циклов внутри цикла
добрый вечер форумчане. в общем мне надо составить комбинацию M-значных цифр,...

Задать количество итераций цикла
как сделать так чтоб цикл считал столько раз сколько я ввел? почему выводит...

Как посчитать количество итераций цикла?
Не совсем представляю, как это осуществить. Т.е. возвращается х, а еще что-то...

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

Изменить переменную внутри цикла for
Сегодня только начал знакомиться с Go. Столкнулся с таким поведением: ...

26
Catstail
Модератор
24154 / 12143 / 2178
Регистрация: 12.02.2012
Сообщений: 19,721
21.08.2012, 18:11 2
Такой стиль программирования чреват очень трудно распознаваемыми ошибками... И не факт, что For - Next так уж лучше While.
0
Formanter
12 / 12 / 2
Регистрация: 07.04.2010
Сообщений: 74
21.08.2012, 18:32  [ТС] 3
С учетом того что конец цикла отодвинулся только на единичку, то искал долго.
На старых машинах For - Next работал заметно шустрее.
0
Catstail
Модератор
24154 / 12143 / 2178
Регистрация: 12.02.2012
Сообщений: 19,721
21.08.2012, 18:51 4
Цитата Сообщение от Formanter Посмотреть сообщение
На старых машинах For - Next работал заметно шустрее
- шустрее ЧЕГО?
0
Quiet Snow
4409 / 1305 / 376
Регистрация: 25.04.2010
Сообщений: 3,350
22.08.2012, 10:37 5
- шустрее ЧЕГО?
видимо этого
Цитата Сообщение от Catstail Посмотреть сообщение
уж лучше While
естественно со счётчиком...
0
Formanter
12 / 12 / 2
Регистрация: 07.04.2010
Сообщений: 74
22.08.2012, 16:15  [ТС] 6

Не по теме:

Прошу прощения, отсутствовал.


Quiet Snow ответил верно. Цикл For - Next работал быстрее чем While-счетчик-Wend
0
Catstail
Модератор
24154 / 12143 / 2178
Регистрация: 12.02.2012
Сообщений: 19,721
22.08.2012, 17:37 7
Про ZX-Spectrum не скажу, но вот результат тестирования трех видов циклов, которые делают одно и то же для Visual Basic:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Private Declare Function GetTickCount Lib "kernel32" () As Long
Sub Test_1()
    TBeg& = GetTickCount
    For i& = 1 To 1000
        S# = 0
        For j& = 1 To 10000   ' Обычный For-Next
            S# = S# + 2 * (j& - 1) + 1
        Next j&
    Next i&
    TEnd& = GetTickCount
    Me.Label1.Caption = CStr(TEnd& - TBeg&)
End Sub
 
Sub Test_2()
    TBeg& = GetTickCount
    For i& = 1 To 1000
        S# = 0
        j& = 1
        Do While (j& <= 10000) ' DO-While
            S# = S# + 2 * (j& - 1) + 1
            j& = j& + 1
        Loop
    Next i&
    TEnd& = GetTickCount
    Me.Label2.Caption = CStr(TEnd& - TBeg&)
End Sub
 
Sub Test_3()
    TBeg& = GetTickCount
    For i& = 1 To 1000
        S# = 0
        j& = 1
        Do                   ' бесконечный DO с явным выходом
            S# = S# + 2 * (j& - 1) + 1
            j& = j& + 1
            If j& > 10000 Then Exit Do
        Loop
    Next i&
    TEnd& = GetTickCount
    Me.Label3.Caption = CStr(TEnd& - TBeg&)
End Sub
 
Private Sub Command1_Click()
    Test_1
    Test_2
    Test_3
End Sub
Результат тестирования представлен на миниатюре. Действительно, For-Next незначительно (весьма незначительно!) быстрее Do While и вполне сопоставим с Do Loop...
0
Изображения
 
Quiet Snow
4409 / 1305 / 376
Регистрация: 25.04.2010
Сообщений: 3,350
22.08.2012, 18:09 8
Ну во-первых, лонга нам не надо при тестировании конструкций

j& = j& + 1

т.е. ставим инты на внешнем и внутреннем цикле + увеличиваем внешний цикл(внутренний цикл ставим - предел инта).

а во-вторых вот эта штука хавает всё время(вычитание, умножение, конверт типа и 2
сложения дабла), хуже только тригонометрия и извлечение корня

S# = S# + 2 * (j& - 1) + 1

уберите её вообще оттуда и измеряйте чистое время работы циклов, в for счётчик уже есть,
его не может не быть т.к. сам for работает, если не верите что он работает, поставьте глобальный каунтер и смотрите по таймеру...
+ время работы программы должно быть большое, секунд 30 минимум, чтобы разницу было явно видно.
0
Catstail
Модератор
24154 / 12143 / 2178
Регистрация: 12.02.2012
Сообщений: 19,721
22.08.2012, 18:13 9
Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
Ну во-первых, лонга нам не надо
- почему? Во-первых, long для современных процессоров - более родной тип данных, чем integer, а во-вторых - ведь все три цикла используют один тип...

Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
вот эта штука хавает всё время
- и что? Ведь она одинаково "хавает" во всех трех случаях.


Заменил long на integer. Результат ниже. Выводы? 1) Производительность циклов сопоставима 2) циклы с long работают быстрее (о чем я и говорил).

Кстати, "чистое время цикла For без тела" не так-то просто замерить... Не исключено, что компилятор такой цикл просто выкинет. Да и зачем нужен "пустой цикл"?
0
Изображения
 
Catstail
Модератор
24154 / 12143 / 2178
Регистрация: 12.02.2012
Сообщений: 19,721
22.08.2012, 18:21 10
Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
время работы программы должно быть большое, секунд 30 минимум, чтобы разницу было явно видно.
- я считаю системные "тики". Нет необходимости ждать 30 сек. Все и так достаточно.
0
Quiet Snow
4409 / 1305 / 376
Регистрация: 25.04.2010
Сообщений: 3,350
22.08.2012, 18:29 11
- и что?
Считаем не то время, не время работы циклов, а время выполнения ЭТОЙ конструкции,
которая хавает в десятки раз больше времени, чем работа цикла.
Создам как я ща макрос и тоже проверю, самому интересно.
0
Catstail
Модератор
24154 / 12143 / 2178
Регистрация: 12.02.2012
Сообщений: 19,721
22.08.2012, 18:32 12
Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
Создам как я ща макрос и тоже проверю, самому интересно.
- я тестировал не макросы, а нативный код в VB (в VBA выполняется интерпретация и результат будет другой).


Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
Считаем не то время, не время работы циклов, а время выполнения ЭТОЙ конструкции,
- а зачем нужны циклы без тела?
0
Quiet Snow
4409 / 1305 / 376
Регистрация: 25.04.2010
Сообщений: 3,350
22.08.2012, 18:57 13
а нативный код в VB
А человек говорит про цитирую

Цитата Сообщение от Formanter Посмотреть сообщение
VBA
поэтому мой код на основе вашего и результат теста в Excel макросе:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Private Declare Function GetTickCount Lib "kernel32" () As Long
Sub Test_1()
    TBeg& = GetTickCount
    For i% = 1 To 1000
        For j% = 1 To 32000
        Next j%
    Next i%
    TEnd& = GetTickCount
    Label1.Caption = CStr(TEnd& - TBeg&)
End Sub
 
Sub Test_2()
    TBeg& = GetTickCount
    For i% = 1 To 1000
        j% = 1
        While j% <= 32000
            j% = j% + 1
        Wend
    Next i%
    TEnd& = GetTickCount
    Label2.Caption = CStr(TEnd& - TBeg&)
End Sub
 
Sub Test_3()
    TBeg& = GetTickCount
    For i% = 1 To 1000
        j% = 1
        Do
            j% = j% + 1
            If j% > 32000 Then Exit Do
        Loop
    Next i%
    TEnd& = GetTickCount
    Label3.Caption = CStr(TEnd& - TBeg&)
End Sub
 
Private Sub CommandButton1_Click()
    Test_1
    Test_2
    Test_3
End Sub
Результат:
250
2125
2250

Но если хотите, я специально для вас, накакаю себе в комп визуал бейсиком и
протестирую, делов то 15 минут...

в VBA выполняется интерпретация
Я вкурсе, потому и не понимаю нафига оно ТС'у сдалось , ничего он не выжмет с VBA не припаяв к нему dll'ку написанную на асме или на с...

- а зачем нужны циклы без тела?
За тем что счётчик... Я же говорю если не верите, ставьте глобал каунтер и смотрите по таймеру...
0
Catstail
Модератор
24154 / 12143 / 2178
Регистрация: 12.02.2012
Сообщений: 19,721
22.08.2012, 19:28 14
Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
Но если хотите, я специально для вас, накакаю себе в комп визуал бейсиком и протестирую, делов то 15 минут...
- вы полагаете, что я фальсифицирую результаты тестирования? Зря...

Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
За тем что счётчик...
- что вы понимаете под "счетчиком"?

Добавлено через 8 минут
В VBA цикл FOR примерно вдвое быстрее. Мой тест на длинных целых дает:

1344
2297
2156

На коротких целых:

1406
2312
2906

Так что, применительно к VBA вы правы.

Добавлено через 1 минуту
Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
я специально для вас, накакаю себе в комп
- ради Бога, не нужно!
0
Quiet Snow
4409 / 1305 / 376
Регистрация: 25.04.2010
Сообщений: 3,350
22.08.2012, 19:47 15
- вы полагаете, что я фальсифицирую результаты тестирования? Зря...
Зачем, я вам верю. Вижу же код. Просто хочу показать другую сторону монеты.
Мой код и данные тоже реальны, то что цикл работает - тоже реально...
Создайте макрос запустите посмотрите.

- что вы понимаете под "счетчиком"?
То что в конструкции FOR он встроен как бы, а в других конструкциях приходится гениально
"высокоуровнево" решать этот вопрос, если вы когда н-ть кодили на асме, то понимаете как
неповоротлив ВУ-код, он не раскладывается по конвеерам, не оптимизирует работу с регистрами,
переходы ставит не там где надо, убивая кеш команд насмерть и предсказание переходов.
Человек не спроста задал этот вопрос, значит он упёрся в эту производительность и есть вероятность,
что он пытается что-то мелкое делать и видит существенную разницу ставя разные циклы.
И тут ему приходится ставить лишний счётчик и проверку условия(всё это ведь в FOR'е работает
побыстрее ясен пень, чем отдельно).
0
Catstail
Модератор
24154 / 12143 / 2178
Регистрация: 12.02.2012
Сообщений: 19,721
22.08.2012, 19:51 16
Цитата Сообщение от >Quiet Snow< Посмотреть сообщение
значит он упёрся в эту производительность
- уперся в производительность, программируя на бэйсике?
0
locm
22.08.2012, 19:59
  #17

Не по теме:

Цитата Сообщение от Catstail Посмотреть сообщение
уперся в производительность, программируя на бэйсике
А что программируя на бейсике, компы автоматом начинают работать на сверхпроводниковых чипах в производительностью стремящейся к бесконечности?:D=-O

0
Catstail
Модератор
24154 / 12143 / 2178
Регистрация: 12.02.2012
Сообщений: 19,721
22.08.2012, 20:05 18
Цитата Сообщение от locm Посмотреть сообщение
А что программируя на бейсике, компы автоматом начинают работать
- "...подъезжая к сей станции, с моей головы слетела шляпа! (А.П. Чехов)" Но, если серьезно, то все очень просто: если бэйсик-программист "упирается в нехватку производительности", то есть только 2 способа:

1) радикально изменить алгоритм задачи
2) сменить язык программирования (на C/С++ или ассемблер)

И, вне всякого сомнения, выигрывать копейки на цикле FOR - не тот путь, который приведет к решению.
0
locm
22.08.2012, 20:09
  #19

Не по теме:

Цитата Сообщение от Catstail Посмотреть сообщение
2) сменить язык программирования (на C/С++ или ассемблер)
Зачем сразу асм?
Достаточно асм вставок в код. Это позволит получить желаемую производительность при минимальных модификациях кода.

0
Quiet Snow
4409 / 1305 / 376
Регистрация: 25.04.2010
Сообщений: 3,350
22.08.2012, 20:10 20
- уперся в производительность, программируя на бэйсике?
В другом смысле, не в смысле выжал всю производительность из компа, а тупо упёрся, зная
что прога может работать быстрее и работает на других видах бейсика, я же тоже смотрел и
сравнивал как QB работает с циклами, человек явно в недоумении, про спектрум я ваще молчу
с его 3-мя мегагерцами, там каждый такт на счету...
0
22.08.2012, 20:10
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.08.2012, 20:10

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

Подсчитать количество итераций цикла в единицу времени
Хочу подсчитать производительность проги, зациклив её на час и подсчитав...

Количество итераций цикла с одинаковым значением кратного
Здраствуйте. Подскажите пожалуйста как подсчитать количество итераций с...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru