Помогите разобраться с тормозами программы!

Предыдущая тема Следующая тема Перейти вниз

Помогите разобраться с тормозами программы!

Сообщение  Black Doomer в Вт Авг 23, 2011 3:30 am

Данная программа была мною написана специально для оптимизации карт игры Doom 2D Multiplayer на старом досовом QuickBASIC'е.
Но так как DOS уже ушёл в историю, а игра написана для Windows, то и хотелось бы скомпилировать сию программу под Windows, чтобы пользователи 64-битных компьютеров тоже могли ею пользоваться.
Вычитал, что для компиляции QuickBASIC-программ под новые системы можно использовать компилятор FreeBASIC с ключом -lang qb. Но вот незадача: скомпилированная программа работает в разы медленнее своего досового собрата, запущенного из-под NTVDM (к примеру: карта в 37262 строчки оптимизировалась в NTVDM минут за 5, а под скомпилированная под Win32 программа работала несколько часов).
Может кто-нибудь подсказать, в чём здесь дело? На всякий случай прикладываю код:

Код:
ON ERROR GOTO UNKNOWNERROR          'определяем подпрограмму обработки ошибок
'подготавливаем компьютер к работе программы
CLS : RESET                        'очищаем экран и закрываем все файлы
COLOR 3
loadloc = 1
IF UCASE$(COMMAND$) = "-INARRCAP" THEN
DO UNTIL arrcap >= 8
LOCATE 1, 1: INPUT "ENTER ARRAY SIZE: ", arrcap
LOOP
loadloc = loadloc + 1
ELSE
arrcap = 10000                      'размер массива для данных карты
END IF
DIM srcmap(1 TO arrcap) AS SINGLE  'создаем массив для тайлов
DIM info(1 TO 500) AS STRING        'создаем массив для описывающей информации
x = 0                              'переменная для циклов
x1 = 0                              'переменная для циклов
x2 = 0                              'переменная для циклов
seekpos = 0                        'позиция считывания в файле карты
cycles = 1                          'номер цикла работы
mapload = 0                        'счетчик загруженных строк
mapopt = 0                          'счетчик оптимизации
mapcomp = 0                        'счетчик строк, загруженных в этом цикле
mapsave = 0                        'счетчик сохраненных в MAP_NEW.DLV строк
fcomp = 1                          'позиция тайла-образца
scomp = 5                          'позиция проверяемого тайла
loading = 0                        'счетчик загрузки программы
temp$ = ""                          'переменная для временных данных
mapname$ = ""                      'имя файла карты
outname$ = ""
tstart$ = ""
tend$ = ""

'забиваем массивы пропускаемыми значениями
PRINT "LOADING: 0"
FOR x = 1 TO arrcap
srcmap(x) = -32767
loading = loading + 1
LOCATE loadloc, 9: PRINT loading
NEXT x
FOR x = 1 TO 500
info(x) = "*|EMPTYARRSLOT|*"
loading = loading + 1
LOCATE loadloc, 9: PRINT loading
NEXT x
CLS
PRINT "Doom2DMP Map Optimizer v1.2 by Black Doomer."
DO UNTIL mapname$ <> ""
LOCATE 2, 1: INPUT "ENTER MAP FILENAME: ", mapname$    '10
LOOP
'IF mapname$ = "" THEN
'BEEP
'GOTO 10
'END IF
IF UCASE$(mapname$) = "/EXIT" OR UCASE$(mapname$) = "/QUIT" THEN
RESET: CLS : ERASE srcmap, info: SYSTEM
END IF
IF UCASE$(RIGHT$(mapname$, 4)) <> ".DLV" THEN mapname$ = mapname$ + ".DLV"
LOCATE 3, 1: INPUT "ENTER OUTPUT MAP FILENAME (MAP_NEW.DLV is default): ", outname$
tstart$ = TIME$
IF outname$ = "" THEN outname$ = "MAP_NEW.DLV"
IF UCASE$(RIGHT$(outname$, 4)) <> ".DLV" THEN outname$ = outname$ + ".DLV"

OPEN mapname$ FOR INPUT AS #1 LEN = 2
OPEN outname$ FOR OUTPUT AS #2 LEN = 2
OPEN "MAPOPT12.LOG" FOR APPEND AS #3
IF SEEK(3) = 1 THEN
PRINT #3, "Doom2DMP Map Optimizer log file."
PRINT #3, "Creating time: "; TIME$
PRINT #3, "=*=*=*=*=*=*=*=*=*="
END IF
FOR x = 1 TO 7
INPUT #1, info(x)
mapload = mapload + 1
LOCATE 3, 13: PRINT mapload
NEXT x
FOR x = 8 TO 500
INPUT #1, temp$
IF UCASE$(LEFT$(temp$, 5)) = "DATA\" THEN
info(x) = temp$
mapload = mapload + 1
LOCATE 3, 13: PRINT mapload
ELSE
seekpos = SEEK(1) - LEN(temp$) - 2
SEEK #1, seekpos
EXIT FOR
END IF
NEXT x

CLS
LOCATE 1, 1: PRINT "Working cycle: 1"
LOCATE 3, 1: PRINT "Loading map: 0"
LOCATE 5, 1: PRINT "Optimizing map: 0"
LOCATE 7, 1: PRINT "Saving map: 0"
LOCATE 10, 1: PRINT "EXAMPLE TILE:"; SPACE$(7); "CHECKING TILE:"
FOR x = 1 TO 500
IF info(x) = "*|EMPTYARRSLOT|*" THEN EXIT FOR
PRINT #2, info(x)
mapsave = mapsave + 1
LOCATE 7, 12: PRINT mapsave
NEXT x

DO
LOCATE 1, 15: PRINT cycles
FOR x = 1 TO arrcap
INPUT #1, srcmap(x)
mapload = mapload + 1
LOCATE 3, 13: PRINT mapload
mapcomp = mapcomp + 1
IF EOF(1) <> 0 THEN EXIT FOR
NEXT x
FOR x1 = 1 TO mapcomp / 4 - 1
    FOR x2 = 1 TO mapcomp / 4 - x1
        IF srcmap(fcomp) = -32767 THEN
            IF srcmap(fcomp + 1) = -32767 THEN
                IF srcmap(fcomp + 2) = -32767 THEN
                    IF srcmap(fcomp + 3) = -32767 THEN
                        EXIT FOR
                    END IF
                END IF
            END IF
        END IF
    LOCATE 17, 1: PRINT "X1:", x1; SPACE$(10)          'дебаг-функция
    LOCATE 18, 1: PRINT "X2:", x2; SPACE$(10)          'дебаг-функция
    LOCATE 19, 1: PRINT "FCOMP:", fcomp; SPACE$(10)    'дебаг-функция
    LOCATE 20, 1: PRINT "SCOMP:", scomp; SPACE$(10)    'дебаг-функция
    LOCATE 11, 1: PRINT srcmap(fcomp); SPACE$(7)
    LOCATE 11, 21: PRINT srcmap(scomp); SPACE$(7)
    LOCATE 12, 1: PRINT srcmap(fcomp + 1); SPACE$(7)
    LOCATE 12, 21: PRINT srcmap(scomp + 1); SPACE$(7)
    LOCATE 13, 1: PRINT srcmap(fcomp + 2); SPACE$(7)
    LOCATE 13, 21: PRINT srcmap(scomp + 2); SPACE$(7)
    LOCATE 14, 1: PRINT srcmap(fcomp + 3); SPACE$(7)
    LOCATE 14, 21: PRINT srcmap(scomp + 3); SPACE$(7)
        IF srcmap(fcomp) = srcmap(scomp) THEN
            IF srcmap(fcomp + 1) = srcmap(scomp + 1) THEN
                IF srcmap(fcomp + 2) = srcmap(scomp + 2) THEN
                    IF srcmap(fcomp + 3) = srcmap(scomp + 3) THEN
                    srcmap(scomp) = -32767
                    srcmap(scomp + 1) = -32767
                    srcmap(scomp + 2) = -32767
                    srcmap(scomp + 3) = -32767
                    mapopt = mapopt + 1
                    LOCATE 5, 16: PRINT mapopt
                    END IF
                END IF
            END IF
        END IF
    scomp = scomp + 4
    NEXT x2
fcomp = fcomp + 4
scomp = fcomp + 4
NEXT x1

FOR x = 1 TO arrcap
IF srcmap(x) <> -32767 THEN
WRITE #2, srcmap(x)
mapsave = mapsave + 1
LOCATE 7, 12: PRINT mapsave
END IF
NEXT x
IF EOF(1) <> 0 THEN
tend$ = TIME$
EXIT DO
END IF
cycles = cycles + 1
mapcomp = 0
fcomp = 1
scomp = 5
FOR x = 1 TO arrcap
srcmap(x) = -32767
NEXT x
LOOP

PRINT #3, "Input map filename: "; mapname$
PRINT #3, "Output map filename: "; outname$
PRINT #3, "Starting time: "; tstart$
PRINT #3, "Ending time: "; tend$
PRINT #3, CHR$(13)
PRINT #3, "Working cycles:"; cycles
PRINT #3, "Optimizing map (deleted tiles):"; mapopt
PRINT #3, "Array size:"; arrcap
PRINT #3, "Non-optimized map size:"; LOF(1); "bytes."
PRINT #3, "Optimized map size:"; LOF(2); "bytes."
IF LOF(1) = LOF(2) THEN
PRINT #3, CHR$(13)
PRINT #3, "[!] Output map was deleted, because no deleted tiles."
END IF
PRINT #3, "=*=*=*=*=*=*=*=*=*="
PRINT #3, CHR$(13)
CLOSE #3

LOCATE 17, 1: PRINT "ALL DONE."; SPACE$(15)
LOCATE 18, 1: PRINT "Non-optimized map size:"; LOF(1); "bytes."; SPACE$(15)
LOCATE 19, 1: PRINT "Optimized map size:"; LOF(2); "bytes."; SPACE$(15)
IF LOF(1) = LOF(2) THEN
CLOSE #2
KILL outname$
LOCATE 20, 1: PRINT outname$; " was deleted."; SPACE$(15)
LOCATE 21, 1: PRINT "Press any key to quit."; SPACE$(15)
ELSE
LOCATE 20, 1: PRINT "Press any key to quit."; SPACE$(15)
END IF
BEEP
RESET: SLEEP: CLS : ERASE srcmap, info: SYSTEM

UNKNOWNERROR:
LOCATE 22, 1: PRINT "UNKNOWN ERROR;"
LOCATE 23, 1: PRINT "press any key to quit."
BEEP
RESET: SLEEP: CLS : ERASE srcmap, info: SYSTEM

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Помогите разобраться с тормозами программы!

Сообщение  trew в Вт Авг 23, 2011 6:15 am

Запиши в начале кода:

#lang "qb"

Дальше работай в редакторе FbEdit как с обычным Freebasic файлом. Можно и в отладчике погонять (скомпилировать как QB Console debug), можно и так найти проблемный участок.

P.S Я конечно могу ошибаться, но судя по коду нужен файл карты. Если не получится у самого, выложи его , я попробую...

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Помогите разобраться с тормозами программы!

Сообщение  Black Doomer в Вт Авг 23, 2011 8:02 am

Вот файл карты:
ХТТП://narod.ru/disk/22609053001/testmap.7z.html
Должно удалиться 5030 тайлов (строка Optimizing Map) при размере массива arrcap 10000.
Редактор самих карт можно скачать здесь: ХТТП://doom2d.org/forum/viewtopic.php?f=19&t=771

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Помогите разобраться с тормозами программы!

Сообщение  trew в Вт Авг 23, 2011 9:22 am

Black Doomer пишет:Вот файл карты:
ХТТП://narod.ru/disk/22609053001/testmap.7z.html
Должно удалиться 5030 тайлов (строка Optimizing Map) при размере массива arrcap 10000.
Редактор самих карт можно скачать здесь: ХТТП://doom2d.org/forum/viewtopic.php?f=19&t=771

Я сильно не смотрел код, но первое что бросается в глаза, это использование консольного окна. А это точно тормоза. Попробуй графическое окно, в начале кода: Screen 1.
Вопрос: сколько времени затрачивается с этим файлом под DOS ? Просто нужно хотя знать, к чему стремиться Very Happy

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Помогите разобраться с тормозами программы!

Сообщение  trew в Вт Авг 23, 2011 10:38 am

delete


Последний раз редактировалось: trew (Вт Авг 23, 2011 11:35 am), всего редактировалось 1 раз(а)

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Помогите разобраться с тормозами программы!

Сообщение  trew в Вт Авг 23, 2011 11:34 am

Вот версия переписанная полностью под FreeBasic, выполняет оптимизацию файла за несколько секунд:

Код:


Screen 1
On ERROR GOTO UNKNOWNERROR          'определяем подпрограмму обработки ошибок
'подготавливаем компьютер к работе программы
CLS : RESET                        'очищаем экран и закрываем все файлы
COLOR 3
Dim Shared As Integer arrcap,x,x1,x2,seekpos,cycles=1,loadloc=1
Dim shared As Integer mapcomp,mapsave,fcomp=1,scomp=5,loading,mapload,mapopt
Dim As String temp,mapname,outname,tstart,tend

IF UCASE$(Command$) = "-INARRCAP" THEN
   DO UNTIL arrcap >= 8
      LOCATE 1, 1: INPUT "ENTER ARRAY SIZE: ", arrcap
   LOOP
   loadloc = loadloc + 1
ELSE
   arrcap = 10000                      'размер массива для данных карты
END If

'twoP=0 ' флаг для потока
Dim Shared srcmap(1 TO arrcap) AS SINGLE  'создаем массив для тайлов
DIM info(1 TO 500) AS STRING        'создаем массив для описывающей информации
x = 0                              'переменная для циклов
x1 = 0                              'переменная для циклов
x2 = 0                              'переменная для циклов
seekpos = 0                        'позиция считывания в файле карты
cycles = 1                          'номер цикла работы
mapload = 0                        'счетчик загруженных строк
mapopt = 0                          'счетчик оптимизации
mapcomp = 0                        'счетчик строк, загруженных в этом цикле
mapsave = 0                        'счетчик сохраненных в MAP_NEW.DLV строк
fcomp = 1                          'позиция тайла-образца
scomp = 5                          'позиция проверяемого тайла
loading = 0                        'счетчик загрузки программы
temp = ""                          'переменная для временных данных
mapname = ""                      'имя файла карты
outname = ""
tstart = ""
tend = ""
'забиваем массивы пропускаемыми значениями
PRINT "LOADING: 0"
FOR x = 1 TO arrcap
   srcmap(x) = -32767
   loading = loading + 1
   LOCATE loadloc, 9: PRINT loading
NEXT x
FOR x = 1 TO 500
   info(x) = "*|EMPTYARRSLOT|*"
   loading = loading + 1
   LOCATE loadloc, 9: PRINT loading
NEXT x
CLS
PRINT "Doom2DMP Map Optimizer v1.2 by Black Doomer."
DO UNTIL mapname <> ""
   LOCATE 2, 1: INPUT "ENTER MAP FILENAME: ", mapname    '10
LOOP
'IF mapname$ = "" THEN
'BEEP
'GOTO 10
'END IF
IF UCASE$(mapname) = "/EXIT" OR UCase$(mapname) = "/QUIT" THEN
   RESET: CLS : ERASE srcmap, info: SYSTEM
END IF
IF UCASE$(Right$(mapname, 4)) <> ".DLV" THEN mapname = mapname + ".DLV"
LOCATE 3, 1: INPUT "ENTER OUTPUT MAP FILENAME (MAP_NEW.DLV is default): ", outname
tstart = Time$
IF outname = "" THEN outname = "MAP_NEW.DLV"
IF UCASE$(Right$(outname, 4)) <> ".DLV" THEN outname = outname + ".DLV"

OPEN mapname FOR INPUT AS #1 LEN = 2
OPEN outname FOR OUTPUT AS #2 LEN = 2
OPEN "MAPOPT12.LOG" FOR APPEND AS #3
IF SEEK(3) = 1 THEN
   PRINT #3, "Doom2DMP Map Optimizer log file."
   PRINT #3, "Creating time: "; Time$
   PRINT #3, "=*=*=*=*=*=*=*=*=*="
END IF
FOR x = 1 TO 7
   INPUT #1, info(x)
   mapload = mapload + 1
   LOCATE 3, 13: PRINT mapload
NEXT x
FOR x = 8 TO 500
   INPUT #1, temp
   IF UCASE$(Left$(temp, 5)) = "DATA\" THEN
      info(x) = temp
      mapload = mapload + 1
      LOCATE 3, 13: PRINT mapload
   ELSE
      seekpos = SEEK(1) - LEN(temp) - 2
      SEEK #1, seekpos
      EXIT FOR
   END IF
NEXT x

CLS
LOCATE 1, 1: PRINT "Working cycle: 1"
LOCATE 3, 1: PRINT "Loading map: 0"
LOCATE 5, 1: PRINT "Optimizing map: 0"
LOCATE 7, 1: PRINT "Saving map: 0"
LOCATE 10, 1: PRINT "EXAMPLE TILE:"; Space$(7); "CHECKING TILE:"
FOR x = 1 TO 500
   IF info(x) = "*|EMPTYARRSLOT|*" THEN EXIT FOR
   PRINT #2, info(x)
   mapsave = mapsave + 1
   LOCATE 7, 12: PRINT mapsave
NEXT x

DO
   LOCATE 1, 15: PRINT cycles
   FOR x = 1 TO arrcap
      INPUT #1, srcmap(x)
      mapload = mapload + 1
      LOCATE 3, 13: PRINT mapload
      mapcomp = mapcomp + 1
      IF EOF(1) <> 0 THEN EXIT FOR
   NEXT x

   FOR x1 = 1 TO mapcomp / 4 - 1
      FOR x2 = 1 TO mapcomp / 4 - x1
         IF srcmap(fcomp) = -32767 THEN
            IF srcmap(fcomp + 1) = -32767 THEN
               IF srcmap(fcomp + 2) = -32767 THEN
                  IF srcmap(fcomp + 3) = -32767 THEN
                     EXIT FOR
                  END IF
               END IF
            END IF
         END If
         If x1>=mapcomp / 4 - 1 then
            LOCATE 17, 1: PRINT "X1:", x1; SPACE$(10)          'дебаг-функция
            LOCATE 18, 1: PRINT "X2:", x2; SPACE$(10)          'дебаг-функция
            LOCATE 19, 1: PRINT "FCOMP:", fcomp; SPACE$(10)    'дебаг-функция
            LOCATE 20, 1: PRINT "SCOMP:", scomp; SPACE$(10)    'дебаг-функция
            LOCATE 11, 1: PRINT srcmap(fcomp); SPACE$(7)
            LOCATE 11, 21: PRINT srcmap(scomp); SPACE$(7)
            LOCATE 12, 1: PRINT srcmap(fcomp + 1); SPACE$(7)
            LOCATE 12, 21: PRINT srcmap(scomp + 1); SPACE$(7)
            LOCATE 13, 1: PRINT srcmap(fcomp + 2); SPACE$(7)
            LOCATE 13, 21: PRINT srcmap(scomp + 2); SPACE$(7)
            LOCATE 14, 1: PRINT srcmap(fcomp + 3); SPACE$(7)
            LOCATE 14, 21: PRINT srcmap(scomp + 3); SPACE$(7)
         EndIf
         IF srcmap(fcomp) = srcmap(scomp) THEN
            IF srcmap(fcomp + 1) = srcmap(scomp + 1) THEN
               IF srcmap(fcomp + 2) = srcmap(scomp + 2) THEN
                  IF srcmap(fcomp + 3) = srcmap(scomp + 3) THEN
                     srcmap(scomp) = -32767
                     srcmap(scomp + 1) = -32767
                     srcmap(scomp + 2) = -32767
                     srcmap(scomp + 3) = -32767
                     mapopt = mapopt + 1
                     LOCATE 5, 16: PRINT mapopt
                  END IF
               END IF
            END IF
         END IF
         scomp = scomp + 4
      NEXT x2
      fcomp = fcomp + 4
      scomp = fcomp + 4
   NEXT x1

   FOR x = 1 TO arrcap
      IF srcmap(x) <> -32767 THEN
         WRITE #2, srcmap(x)
         mapsave = mapsave + 1
         LOCATE 7, 12: PRINT mapsave
      END IF
   NEXT x
   IF EOF(1) <> 0 THEN
      tend = Time$
      EXIT DO
   END IF
   cycles = cycles + 1
   mapcomp = 0
   fcomp = 1
   scomp = 5
   FOR x = 1 TO arrcap
      srcmap(x) = -32767
   NEXT x
Loop

Print #3, "Input map filename: "; mapname
PRINT #3, "Output map filename: "; outname
PRINT #3, "Starting time: "; tstart
PRINT #3, "Ending time: "; tend
PRINT #3, Chr$(13)
PRINT #3, "Working cycles:"; cycles
PRINT #3, "Optimizing map (deleted tiles):"; mapopt
PRINT #3, "Array size:"; arrcap
PRINT #3, "Non-optimized map size:"; LOF(1); "bytes."
PRINT #3, "Optimized map size:"; LOF(2); "bytes."
IF LOF(1) = LOF(2) THEN
   PRINT #3, Chr$(13)
   PRINT #3, "[!] Output map was deleted, because no deleted tiles."
END IF
PRINT #3, "=*=*=*=*=*=*=*=*=*="
PRINT #3, Chr$(13)
CLOSE #3

LOCATE 17, 1: PRINT "ALL DONE."; Space$(15)
LOCATE 18, 1: PRINT "Non-optimized map size:"; LOF(1); "bytes."; Space$(15)
LOCATE 19, 1: PRINT "Optimized map size:"; LOF(2); "bytes."; Space$(15)
IF LOF(1) = LOF(2) THEN
   CLOSE #2
   KILL outname
   LOCATE 20, 1: PRINT outname; " was deleted."; Space$(15)
   LOCATE 21, 1: PRINT "Press any key to quit."; Space$(15)
ELSE
   LOCATE 20, 1: PRINT "Press any key to quit."; SPACE$(15)
END IF
BEEP
RESET: SLEEP: CLS : ERASE srcmap, info: SYSTEM

UNKNOWNERROR:
LOCATE 22, 1: PRINT "UNKNOWN ERROR;"
LOCATE 23, 1: PRINT "press any key to quit."
BEEP
RESET: SLEEP: CLS : ERASE srcmap, info: System

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Помогите разобраться с тормозами программы!

Сообщение  Саня в Вт Авг 23, 2011 11:22 pm

Вставлю свои пять копеек. Я практичски полностью переписал код, потом модифицировал его, чтоб был полностью под freebasic. было неочень трудно, но день потратил, зато вроде съоптимайзил как мог.. хотя всегда можно лучше.
Код:

Screen 12
On Error GoTo UNKNOWNERROR
Reset:Cls: Color 3
   '   Блок констант

Const ARGUMENT = "-INARRCAP"
Const ARRSIZE = 10000
Const INFOSIZE = 500
Const SKIPVAL = -32767
   'Const EMPTYSLOT = "*|EMPTYARRSLOT|*"   '   Значение было в исходнике, удалено за ненадобностью
Const AUTHOR = "Doom2DMP Map Optimizer v1.2 by Black Doomer."
Const EXIT1 = "/EXIT"
Const EXIT2 = "/QUIT"
Const EXT_SIZE = 4   '   размер расширения файла.
Const EXTENSIONS = ".DLV"
Const NEWFILENAME = "MAP_NEW" + EXTENSIONS
Const RECORDLEN = 2
Const LOGFILE = "MAPOPT12.LOG"
Const DATA4MFILE = "DATA\"
   '   Блок переменных

Dim As UInteger is_end = 0   'достигло ли программа конца, или ошибка
Dim As Integer loadloc = 1
Dim As UInteger seekpos      'позиция считывания в файле карты
Dim As UInteger loading      'счетчик загрузки программы
Dim As UInteger cycles = 1   'номер цикла работы
Dim As UInteger mapload      'счетчик загруженных строк
Dim As UInteger mapopt      'счетчик оптимизации
Dim As UInteger mapcomp      'счетчик строк, загруженных в этом цикле
Dim As UInteger mapsave      'счетчик сохраненных в MAP_NEW.DLV строк
Dim As UInteger arrcap      'размер массива для данных карты
Dim As String temp        'переменная для временных данных
Dim As String mapname      'имя файла карты
Dim As String outname, tstart, tend
Dim As Integer ff1, ff2, ff3
   '

IF UCASE(COMMAND) = ARGUMENT THEN
   Do
      LOCATE 1, 1: Input "ENTER ARRAY SIZE: ", arrcap
   Loop UNTIL arrcap >= 8
   loadloc += 1
ELSE
   arrcap = ARRSIZE
END If

Dim srcmap(1 TO arrcap) AS Single   'создаем массив для тайлов
DIM info(1 TO INFOSIZE) AS String   'создаем массив для описывающей информации

'забиваем массивы пропускаемыми значениями
PRINT "LOADING: 0"
FOR i As UInteger = 1 TO arrcap
   srcmap(i) = SKIPVAL
   loading += 1
   Locate loadloc, 9, 0: PRINT loading
NEXT
/'
   '   В исходнике была, фактически не нужна, удалена для оптимизации
FOR i As UInteger = 1 TO INFOSIZE
   info(i) = EMPTYSLOT
   loading += 1
   Locate loadloc, 9, 0: PRINT loading
Next
'/
   CLS
   Print AUTHOR
   Locate 2, 1
   Print "ENTER MAP FILENAME: ";
Do
   Locate 2, 21
   INPUT "", mapname    ' чтобы не тратилось время на вывод.
Loop Until mapname <> ""

IF UCase(mapname) = EXIT1 Or UCase(mapname) = EXIT2 THEN
   is_end = -1
   Error 0 ' моделируем ошибку, на самом деле ничо особенного не происходит.
END If

IF UCase(Right(mapname, EXT_SIZE)) <> EXTENSIONS THEN mapname += EXTENSIONS

LOCATE 3, 1
   Print "ENTER OUTPUT MAP FILENAME ("; NEWFILENAME; " is default): ";
   INPUT  "", outname
tstart = TIME
IF outname = "" THEN outname = NEWFILENAME
IF UCase(RIGHT(outname, EXT_SIZE) ) <> EXTENSIONS THEN outname += EXTENSIONS
   ff1 = FreeFile
OPEN mapname For Input As ff1 LEN = RECORDLEN
      ff2 = FreeFile
OPEN outname For Output As ff2 LEN = RECORDLEN
   ff3 = FreeFile
OPEN LOGFILE FOR Append AS ff3
If SEEK(ff3) = 1 THEN
   PRINT #ff3, "Doom2DMP Map Optimizer log file."
   PRINT #ff3, "Creating time: "; TIME$
   Print #ff3, "=*=*=*=*=*=*=*=*=*="
END If

FOR i As UInteger = 1 TO 7
   INPUT #ff1, info(i)
   mapload += 1
   Locate 3, 13
   PRINT mapload
Next
For i As UInteger = 8 TO INFOSIZE
   INPUT #ff1, temp
   If UCase(Left(temp, 5)) = DATA4MFILE THEN
      info(i) = temp
      mapload += 1
      LOCATE 3, 13
      Print mapload
   Else
      seekpos = SEEK(ff1) - Len(temp) - 2
      SEEK #ff1, seekpos
      EXIT For
   End IF
Next

CLS
LOCATE 1, 1: PRINT "Working cycle: 1"
LOCATE 3, 1: PRINT "Loading map: 0"
LOCATE 5, 1: PRINT "Optimizing map: 0"
LOCATE 7, 1: PRINT "Saving map: 0"
LOCATE 10, 1: PRINT "EXAMPLE TILE:"; Space(7); "CHECKING TILE:"
FOR i As Integer = 1 TO mapload      '   В исходнике было указано INFOSIZE
   '   IF info(i) = EMPTYSLOT THEN EXIT For
   /'   
      Cтрока была в исходнике, удалена ибо в info( 1..mapload ) загружены строки начинающиеся
      c DATA4MFILE.
   '/
   PRINT #ff2, info(i)
   mapsave += 1
   Locate 7, 12: PRINT i
Next
   mapsave = mapload

DO
   LOCATE 1, 16: PRINT cycles
   FOR i As UInteger = 1 TO arrcap
      IF EOF(ff1) THEN EXIT For
      INPUT #ff1, srcmap(i)
      mapload += 1
      LOCATE 3, 13: PRINT mapload
      mapcomp += 1
   Next
      '   fcomp - позиция тайла-образца
   For fcomp As Integer = 1 TO mapcomp Step 4
      If srcmap(fcomp) = SKIPVAL  AndAlso _
         srcmap(fcomp + 1) = SKIPVAL AndAlso _
        srcmap(fcomp + 2) = SKIPVAL AndAlso _
        srcmap(fcomp + 3) = SKIPVAL Then
           Continue For     
      EndIf
         '   scomp   - позиция проверяемого тайла
     For scomp As Integer = (fcomp + 4) TO mapcomp Step 4         
        LOCATE 17, 1: PRINT "FCOMP:", fcomp; 'Space(10)    'дебаг-функция
        LOCATE 18, 1: PRINT "SCOMP:", scomp; 'Space(10)    'дебаг-функция
        LOCATE 11, 1: PRINT srcmap(fcomp); Space(7)
        LOCATE 11, 21: PRINT srcmap(scomp); Space(7)
        LOCATE 12, 1: PRINT srcmap(fcomp + 1); SPACE(7)
        LOCATE 12, 21: PRINT srcmap(scomp + 1); Space(7)
        LOCATE 13, 1: PRINT srcmap(fcomp + 2); SPACE(7)
        LOCATE 13, 21: PRINT srcmap(scomp + 2); Space(7)
        LOCATE 14, 1: PRINT srcmap(fcomp + 3); Space(7)
        Locate 14, 21: PRINT srcmap(scomp + 3); Space(7)

         If srcmap(fcomp) = srcmap(scomp) AndAlso _
            srcmap(fcomp + 1) = srcmap(scomp + 1) AndAlso _
            srcmap(fcomp + 2) = srcmap(scomp + 2) AndAlso _
            srcmap(fcomp + 3) = srcmap(scomp + 3) Then
              srcmap(scomp) = SKIPVAL
              srcmap(scomp + 1) = SKIPVAL
              srcmap(scomp + 2) = SKIPVAL
              srcmap(scomp + 3) = SKIPVAL
              mapopt += 1
              LOCATE 5, 16: PRINT mapopt
         END If
     Next
   Next

   FOR i As UInteger = 1 TO mapcomp
      IF srcmap(i) <> SKIPVAL THEN
         WRITE #ff2, srcmap(i)
         mapsave += 1
         Locate 7, 12: PRINT mapsave
      End IF
   Next
   IF EOF(ff1) THEN
      tend = Time
      Exit DO
   End IF
   /'
      FOR i As UInteger = 1 TO mapcomp   '   Было в исходнике, не нужно, удалено для оптимизации
         srcmap(i) = SKIPVAL
      Next
   '/
   cycles += 1
   mapcomp = 0
Loop

PRINT #ff3, "Input map filename: "; mapname
PRINT #ff3, "Output map filename: "; outname
PRINT #ff3, "Starting time: "; tstart
PRINT #ff3, "Ending time: "; tend
PRINT #ff3, Chr(13)
PRINT #ff3, "Working cycles:"; cycles
PRINT #ff3, "Optimizing map (deleted tiles):"; mapopt
PRINT #ff3, "Array size:"; arrcap
PRINT #ff3, "Non-optimized map size:"; LOF(ff1); "bytes."
PRINT #ff3, "Optimized map size:"; LOF(ff2); "bytes."
   IF LOF(ff1) = LOF(ff2) THEN
      PRINT #ff3, Chr(13)
      PRINT #ff3, "[!] Output map was deleted, because no deleted tiles."
   END IF
PRINT #ff3, "=*=*=*=*=*=*=*=*=*="
PRINT #ff3, Chr(13)
CLOSE #ff3

LOCATE 17, 1: PRINT "ALL DONE."; Space(15)
LOCATE 18, 1: PRINT "Non-optimized map size:"; LOF(ff1); "bytes."; Space(15)
LOCATE 19, 1: PRINT "Optimized map size:"; LOF(ff2); "bytes."; Space(15)
IF LOF(ff1) = LOF(ff2) THEN
   Close #ff2
   KILL outname
   LOCATE 20, 1: PRINT outname; " was deleted."; Space(15)
   LOCATE 21, 1: PRINT "Press any key to quit."; Space(15)
ELSE
   LOCATE 20, 1: PRINT "Press any key to quit."; Space(15)
END If
   is_end = -1

UNKNOWNERROR:
If is_end = 0 Then
   Locate 22, 1
      Print "UNKNOWN ERROR;"
   LOCATE 23, 1
      Print "press any key to quit."
EndIf
reset
Beep
Sleep
Cls
Erase srcmap, info
System
Однако, у меня выявился баг. в коде приведенном выше на пустом файле( как на других незнаю ) Freefile раза два возвращает одно и тоже значение. Поэтому если прога входит бесконечный цикл,то замените
ff1= freefile ' строка 87
ff2 = freefile ' строка 89
ff3 = freefile ' строка 91
на 1, 2, 3 соответственно.
Я не смог распаковыть архив с примером, поэтому прошу затестить и отписаться.
avatar
Саня

Сообщения : 65
Дата регистрации : 2010-04-28
Возраст : 23
Откуда : Екатеринбург

Посмотреть профиль http://vkontakte.ru/id30561430#/id57547166

Вернуться к началу Перейти вниз

а ларчик просто открывался...

Сообщение  Black Doomer в Ср Авг 24, 2011 2:43 am

Оказалось, причина тормозов была очень и очень проста. Дело в том, что стандартный виндусский cmd.exe не очень быстро выводит текст в консольных приложениях, в отличие от NTVDM. И что вы думаете? Я закомментировал код, отвечающий за вывод значений тайлов на экран, и дебаг-функции, после чего программа стала работать в разы быстрее! Даже быстрее, чем её досовый собрат!
Но я не стал останавливаться на своём QuickBASIC-коде, а взял тот, который написал товарищ trew, за что я и хочу ему выразить огромную человеческую благодарность. Потребовались минимальные штрихи для доведения кода до финального состояния (например, я отключил Screen 1). Но скомпилированная программа и весит меньше (70 кб взамен 89 кб моего кода, скомпилированного в режиме совместимости), и возможностями обладает большими (например, я увеличил стандартный размер массива arrcap до 75000).
Да, думаю, надо уже пересаживаться на FreeBASIC. Может кто-нибудь подсказать хорошие гайды на эту тему? Желательно русскоязычные.

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Помогите разобраться с тормозами программы!

Сообщение  trew в Ср Авг 24, 2011 6:17 am

Может кто-нибудь подсказать хорошие гайды на эту тему? Желательно русскоязычные.
ТУТ и ТУТ

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Помогите разобраться с тормозами программы!

Сообщение  Саня в Ср Авг 24, 2011 9:10 pm

У меня вопрос к Trew: наскоко я понял этот кусок кода:
Код:

 FOR x1 = 1 TO mapcomp / 4 - 1
      FOR x2 = 1 TO mapcomp / 4 - x1
         ..............
        If x1>=mapcomp / 4 - 1 then
            LOCATE 17, 1: PRINT "X1:", x1; SPACE$(10)          'дебаг-функция
            LOCATE 18, 1: PRINT "X2:", x2; SPACE$(10)          'дебаг-функция
            LOCATE 19, 1: PRINT "FCOMP:", fcomp; SPACE$(10)    'дебаг-функция
            LOCATE 20, 1: PRINT "SCOMP:", scomp; SPACE$(10)    'дебаг-функция
            LOCATE 11, 1: PRINT srcmap(fcomp); SPACE$(7)
            LOCATE 11, 21: PRINT srcmap(scomp); SPACE$(7)
            LOCATE 12, 1: PRINT srcmap(fcomp + 1); SPACE$(7)
            LOCATE 12, 21: PRINT srcmap(scomp + 1); SPACE$(7)
            LOCATE 13, 1: PRINT srcmap(fcomp + 2); SPACE$(7)
            LOCATE 13, 21: PRINT srcmap(scomp + 2); SPACE$(7)
            LOCATE 14, 1: PRINT srcmap(fcomp + 3); SPACE$(7)
            LOCATE 14, 21: PRINT srcmap(scomp + 3); SPACE$(7)
        EndIf
         .......
        scomp = scomp + 4
      NEXT x2
      fcomp = fcomp + 4
      scomp = fcomp + 4
  NEXT x1
то проверка
if x1>=mapcomp /4 -1 then ...
будет проводится
( macomp/4 - 1) * ( mapcomp/4 -1 + 1)*(mapcomp/4-1)/2 = mapcomp/8 * (mapcomp/4-1)^2 в худшем случае. Что довольно нехило.(При mapcomp=10000, это уже будет 19507821873750, опять же в худшем случае.. ) При этом случай когда вывод действительно понадобится это только когда x1 достигнет mapcomp/4-1, при этом цикл for x2, выполнится только один раз( mapcomp/4 - ( mapcomp/4 -1 ) = mapcomp/4 - mapcomp /4 -(-1) = 1, и соответственно for x2 = 1 to 1 ). И это изменения?! Тогда уж проще вообще убрать этот кусок. или хотя бы поставить его перед(за) циклом( любым ). имхо.
avatar
Саня

Сообщения : 65
Дата регистрации : 2010-04-28
Возраст : 23
Откуда : Екатеринбург

Посмотреть профиль http://vkontakte.ru/id30561430#/id57547166

Вернуться к началу Перейти вниз

Re: Помогите разобраться с тормозами программы!

Сообщение  trew в Ср Авг 24, 2011 10:51 pm

Саня пишет:У меня вопрос к Trew: наскоко я понял этот кусок кода:
Код:

 FOR x1 = 1 TO mapcomp / 4 - 1
      FOR x2 = 1 TO mapcomp / 4 - x1
         ..............
        If x1>=mapcomp / 4 - 1 then
            LOCATE 17, 1: PRINT "X1:", x1; SPACE$(10)          'дебаг-функция
            LOCATE 18, 1: PRINT "X2:", x2; SPACE$(10)          'дебаг-функция
            LOCATE 19, 1: PRINT "FCOMP:", fcomp; SPACE$(10)    'дебаг-функция
            LOCATE 20, 1: PRINT "SCOMP:", scomp; SPACE$(10)    'дебаг-функция
            LOCATE 11, 1: PRINT srcmap(fcomp); SPACE$(7)
            LOCATE 11, 21: PRINT srcmap(scomp); SPACE$(7)
            LOCATE 12, 1: PRINT srcmap(fcomp + 1); SPACE$(7)
            LOCATE 12, 21: PRINT srcmap(scomp + 1); SPACE$(7)
            LOCATE 13, 1: PRINT srcmap(fcomp + 2); SPACE$(7)
            LOCATE 13, 21: PRINT srcmap(scomp + 2); SPACE$(7)
            LOCATE 14, 1: PRINT srcmap(fcomp + 3); SPACE$(7)
            LOCATE 14, 21: PRINT srcmap(scomp + 3); SPACE$(7)
        EndIf
         .......
        scomp = scomp + 4
      NEXT x2
      fcomp = fcomp + 4
      scomp = fcomp + 4
  NEXT x1
то проверка
if x1>=mapcomp /4 -1 then ...
будет проводится
( macomp/4 - 1) * ( mapcomp/4 -1 + 1)*(mapcomp/4-1)/2 = mapcomp/8 * (mapcomp/4-1)^2 в худшем случае. Что довольно нехило.(При mapcomp=10000, это уже будет 19507821873750, опять же в худшем случае.. ) При этом случай когда вывод действительно понадобится это только когда x1 достигнет mapcomp/4-1, при этом цикл for x2, выполнится только один раз( mapcomp/4 - ( mapcomp/4 -1 ) = mapcomp/4 - mapcomp /4 -(-1) = 1, и соответственно for x2 = 1 to 1 ). И это изменения?! Тогда уж проще вообще убрать этот кусок. или хотя бы поставить его перед(за) циклом( любым ). имхо.

Внимательно посмотри на код. Не получается так понять, засунь туда переменную счетчик, она не обманывая, даст правильный результат. В любом случае задача решена, если учесть что:

карта в 37262 строчки оптимизировалась в NTVDM минут за 5

этот код выполняется за 3 секунды максимум.

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Помогите разобраться с тормозами программы!

Сообщение  Саня в Ср Авг 24, 2011 11:15 pm

В выражении x1>= mapcomp/4-1 зависит только от значений mapcomp & x1. mapcomp формируется до начала обоих циклов, не изменяется в теле цикла, следовательно правая часть выражения получается инвариантной в пределах этих двух циклов, так? Следовательно, значение выражения зависит токмо от x1, так? x1 изменяется в пределах 1..(mapcomp/4 -1 ), при чем изменяется только самим циклом и нигде внутри цикла( внутри цикла for x1 = ... ), так? Максимальное значение x1 может быть mapcomp/4-1, следовательно mapcomp/4-1 >= mapcomp/4-1 будет выполняться. а при x1 = mapcomp/4-2 ? Нет, следовательно во всех предшествовших итерациях этого тоже не будет, я прав? При всех итерациях внутреннего цикла значение меняться не будет, ведь так, a?
avatar
Саня

Сообщения : 65
Дата регистрации : 2010-04-28
Возраст : 23
Откуда : Екатеринбург

Посмотреть профиль http://vkontakte.ru/id30561430#/id57547166

Вернуться к началу Перейти вниз

Re: Помогите разобраться с тормозами программы!

Сообщение  Саня в Ср Авг 24, 2011 11:55 pm

Задача решена, не спорю. насчет скорости. ээмм дело немного субъективно и на разных компах разное покажет. Как я понимю изначальный код был написан давно, но не особо оптимизирован, хотя достточно потратить день-два, имхо. насчет твоего кода. мне не понравилось это решение, потому что хотя на вывод тратится много времени, несравнимо больше, чем на пустое сравнение, но зная в каком месте он будет вызван, что он покажет, можно его перенести в другое место где он не будет требовать сравнений, тем более что это частный случай.
Код:

FOR x1 = 1 TO mapcomp / 4 - 1
      FOR x2 = 1 TO mapcomp / 4 - x1
        IF srcmap(fcomp)       = -32767 AndAlso _
           srcmap(fcomp + 1) = -32767 AndAlso _
            srcmap(fcomp + 2) = -32767 AndAlso _
            srcmap(fcomp + 3) = -32767 THEN
              EXIT FOR
        END If

        IF srcmap(fcomp) = srcmap(scomp) AndAlso _
           srcmap(fcomp + 1) = srcmap(scomp + 1) AndAlso _
            srcmap(fcomp + 2) = srcmap(scomp + 2) AndAlso _
            srcmap(fcomp + 3) = srcmap(scomp + 3) THEN
              srcmap(scomp) = -32767
              srcmap(scomp + 1) = -32767
              srcmap(scomp + 2) = -32767
              srcmap(scomp + 3) = -32767
              mapopt = mapopt + 1
              Locate 5, 16: PRINT mapopt
        END IF
        scomp = scomp + 4
      NEXT x2
      fcomp = fcomp + 4
      scomp = fcomp + 4
NEXT x1

      /'
         так как дело было на последней fcomp указывал на предпоследнюю полезную ячейку массива, а scomp на последнюю
         Если fcomp не был пустой, то она так и останется не пустой, а если следующая за ним ячейка была пустой,
         то ничего не изменится, а если не была пустой и на последней итерации обнулилась, то она была равна предпоследней.
         В обоих случаях это ничего особого н скажет в пользователю.
         Зы: ячейка в данном случае равняется четырем последовательным ячейкам массива и использовалась только для удобства.
      '/
  If srcmap(fcomp - 4)   = -32767 AndAlso _
      srcmap(fcomp - 3)   = -32767 AndAlso _
      srcmap(fcomp - 2) = -32767 AndAlso _
      srcmap(fcomp - 1) = -32767 Then
         scomp = fcomp
         fcomp -= 4
         LOCATE 17, 1: PRINT "X1:", mapcomp/4-1; SPACE$(10) 'дебаг-функция
         LOCATE 18, 1: PRINT "X2:", 1 ; SPACE$(10)          'дебаг-функция
         LOCATE 19, 1: PRINT "FCOMP:", fcomp; SPACE$(10)    'дебаг-функция
         LOCATE 20, 1: PRINT "SCOMP:", scomp; SPACE$(10)    'дебаг-функция
         LOCATE 11, 1: PRINT srcmap(fcomp); SPACE$(7)
         LOCATE 11, 21: PRINT srcmap(scomp); SPACE$(7)
         LOCATE 12, 1: PRINT srcmap(fcomp + 1); SPACE$(7)
         LOCATE 12, 21: PRINT srcmap(scomp + 1); SPACE$(7)
         LOCATE 13, 1: PRINT srcmap(fcomp + 2); SPACE$(7)
         LOCATE 13, 21: PRINT srcmap(scomp + 2); SPACE$(7)
         LOCATE 14, 1: PRINT srcmap(fcomp + 3); SPACE$(7)
         LOCATE 14, 21: PRINT srcmap(scomp + 3); SPACE$(7)
  EndIf
Как-то так.но может потребоваться отладка..
Для всего и всегда может найтись, где ещё улучшить, но не всегда вовремя.
PS: блин, бесит, когда вместо табуляций пробелы.
avatar
Саня

Сообщения : 65
Дата регистрации : 2010-04-28
Возраст : 23
Откуда : Екатеринбург

Посмотреть профиль http://vkontakte.ru/id30561430#/id57547166

Вернуться к началу Перейти вниз

Re: Помогите разобраться с тормозами программы!

Сообщение  Black Doomer в Чт Авг 25, 2011 3:28 am

Я вообще эти дебаг-функции вместе с указанным IF закомментировал. Так что обсуждать их незачем.

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Помогите разобраться с тормозами программы!

Сообщение  Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения