OberonCore https://forum.oberoncore.ru/ |
|
Узнать размер стека https://forum.oberoncore.ru/viewtopic.php?f=2&t=6539 |
Страница 1 из 1 |
Автор: | snark [ Понедельник, 13 Январь, 2020 16:28 ] |
Заголовок сообщения: | Узнать размер стека |
дана программа вывода чисел Фибоначчи MODULE Fibonacci; IMPORT StdLog; PROCEDURE Do*; VAR a, b, c, i, n: INTEGER; BEGIN a := 0; b := 1; n := 9; FOR i := 0 TO n DO c := b; b := a + b; a := c; StdLog.Int( c ); END; END Do; END Fibonacci. все просто-выводит 10 чисел.Если однако убрать строчку n := 9; то программа начнет выводить бесконечное число цифр пока блекбох не зависнет с надписью "NOT RESPONDING". Ясное дело что отведенный операционной системой стек оказался переполненым и ОС аварийно остановила программу.Вопрос: как узнать/вычислить сколько чисел максимально может выдать программа не зависнув? |
Автор: | Sergej Durmanov [ Понедельник, 13 Январь, 2020 18:16 ] |
Заголовок сообщения: | Re: Узнать размер стека |
А причем здесь стек? |
Автор: | Иван Денисов [ Понедельник, 13 Январь, 2020 19:03 ] |
Заголовок сообщения: | Re: Узнать размер стека |
Блэкбокс никогда не инициализирует переменные базовых типов внутри процедур. Это важное свойство для скорости выполнения программ, а также для обучения начинающих программистов. Поэтому ваша обязанность присвоить n какое-то значение. Обнаружить такие ошибки в коде помогает команда Инфо -> Анализировать модуль Вложение: В вашем случае n может быть очень большим, так как содержит "мусор" из оперативной памяти. Поэтому программа выполняется очень долго. Но что хуже — её поведение не определено... ведь n может быть и отрицательным числом. |
Автор: | Иван Денисов [ Понедельник, 13 Январь, 2020 19:22 ] |
Заголовок сообщения: | Re: Узнать размер стека |
Теперь, если понять ваш вопрос иначе... Начнем с того, что Блэкбокс не завис, а продолжает выполнять ваше задание. Но Windows думает, что он завис, поэтому показывает вам сообщение. Он так думает, потому что Блэкбокс перестал отвечать на системные сообщения. Чтобы ББ отвечал на них, и иногда обновлял интерфейс, надо в ваш цикл вставить вызов вот такой процедуры: Код: PROCEDURE ProcessMessages; VAR msg: Win.MSG; res: INTEGER; BEGIN WHILE Win.PeekMessage(msg, 0, 0, 0, Win.PM_REMOVE) # 0 DO res := Win.TranslateMessage(msg); res := Win.DispatchMessageA(msg) END END ProcessMessages; Спасибо Штирлицу, что когда-то показал мне такое решение: viewtopic.php?f=31&t=1937&p=39240#p39240 Получится вот такой код: Код: MODULE Fibonacci; IMPORT StdLog, Win := WinApi; PROCEDURE ProcessMessages; VAR msg: Win.MSG; res: INTEGER; BEGIN WHILE Win.PeekMessage(msg, 0, 0, 0, Win.PM_REMOVE) # 0 DO res := Win.TranslateMessage(msg); res := Win.DispatchMessageA(msg) END END ProcessMessages; PROCEDURE Do*; VAR a, b, c, i, n: INTEGER; BEGIN a := 0; b := 1; n := 900000; FOR i := 0 TO n DO c := b; b := a + b; a := c; StdLog.Int( c ); IF i MOD 10000 = 0 THEN ProcessMessages END END; END Do; END Fibonacci. Однако более правильное решение часто - это разбить вычисления на порции и организовать в очередь рекурсивно устанавливающихся событий. Этот вопрос обсуждался тут: viewtopic.php?f=1&t=130 |
Автор: | Trurl [ Понедельник, 13 Январь, 2020 19:42 ] |
Заголовок сообщения: | Re: Узнать размер стека |
Иван Денисов писал(а): В вашем случае n может быть очень большим, так как содержит "мусор" из оперативной памяти. Поэтому программа выполняется очень долго. Каким бы большим оно не было, это 32-битное число, программа не должна выполнятся слишком долго. Здесь дело в том, что слишком много пишется в журнал. |
Автор: | Иван Денисов [ Понедельник, 13 Январь, 2020 19:46 ] |
Заголовок сообщения: | Re: Узнать размер стека |
Сочетание двух факторов Сложность тела цикла + Число повторений цикла А сложность может быть большой и без вывода в журнал. |
Автор: | ЯрославЗлой [ Четверг, 09 Июль, 2020 09:48 ] |
Заголовок сообщения: | Re: Узнать размер стека |
Trurl писал(а): Иван Денисов писал(а): В вашем случае n может быть очень большим, так как содержит "мусор" из оперативной памяти. Поэтому программа выполняется очень долго. Каким бы большим оно не было, это 32-битное число, программа не должна выполнятся слишком долго. Здесь дело в том, что слишком много пишется в журнал. А можно по подробней в этом плане? |
Автор: | Trurl [ Суббота, 11 Июль, 2020 13:12 ] |
Заголовок сообщения: | Re: Узнать размер стека |
Для любого 32-битного числа (кроме одного) собственно вычисления займут не более нескольких секунд. Но запись в журнал такого количества информации, а затем её отображение - большая нагрузка на систему. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |