Помогите разобраться с тормозами программы!
Участников: 3
FreeBasic :: Программирование :: Общее
Страница 1 из 1
Помогите разобраться с тормозами программы!
Данная программа была мною написана специально для оптимизации карт игры Doom 2D Multiplayer на старом досовом QuickBASIC'е.
Но так как DOS уже ушёл в историю, а игра написана для Windows, то и хотелось бы скомпилировать сию программу под Windows, чтобы пользователи 64-битных компьютеров тоже могли ею пользоваться.
Вычитал, что для компиляции QuickBASIC-программ под новые системы можно использовать компилятор FreeBASIC с ключом -lang qb. Но вот незадача: скомпилированная программа работает в разы медленнее своего досового собрата, запущенного из-под NTVDM (к примеру: карта в 37262 строчки оптимизировалась в NTVDM минут за 5, а под скомпилированная под Win32 программа работала несколько часов).
Может кто-нибудь подсказать, в чём здесь дело? На всякий случай прикладываю код:
Но так как 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
Re: Помогите разобраться с тормозами программы!
Запиши в начале кода:
Дальше работай в редакторе FbEdit как с обычным Freebasic файлом. Можно и в отладчике погонять (скомпилировать как QB Console debug), можно и так найти проблемный участок.
P.S Я конечно могу ошибаться, но судя по коду нужен файл карты. Если не получится у самого, выложи его , я попробую...
#lang "qb"
Дальше работай в редакторе FbEdit как с обычным Freebasic файлом. Можно и в отладчике погонять (скомпилировать как QB Console debug), можно и так найти проблемный участок.
P.S Я конечно могу ошибаться, но судя по коду нужен файл карты. Если не получится у самого, выложи его , я попробую...
trew- Сообщения : 331
Дата регистрации : 2010-10-14
Re: Помогите разобраться с тормозами программы!
Вот файл карты:
ХТТП://narod.ru/disk/22609053001/testmap.7z.html
Должно удалиться 5030 тайлов (строка Optimizing Map) при размере массива arrcap 10000.
Редактор самих карт можно скачать здесь: ХТТП://doom2d.org/forum/viewtopic.php?f=19&t=771
ХТТП://narod.ru/disk/22609053001/testmap.7z.html
Должно удалиться 5030 тайлов (строка Optimizing Map) при размере массива arrcap 10000.
Редактор самих карт можно скачать здесь: ХТТП://doom2d.org/forum/viewtopic.php?f=19&t=771
Re: Помогите разобраться с тормозами программы!
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 ? Просто нужно хотя знать, к чему стремиться
trew- Сообщения : 331
Дата регистрации : 2010-10-14
Re: Помогите разобраться с тормозами программы!
delete
Последний раз редактировалось: trew (Вт Авг 23, 2011 11:35 am), всего редактировалось 1 раз(а)
trew- Сообщения : 331
Дата регистрации : 2010-10-14
Re: Помогите разобраться с тормозами программы!
Вот версия переписанная полностью под 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: Помогите разобраться с тормозами программы!
Вставлю свои пять копеек. Я практичски полностью переписал код, потом модифицировал его, чтоб был полностью под freebasic. было неочень трудно, но день потратил, зато вроде съоптимайзил как мог.. хотя всегда можно лучше.
ff1= freefile ' строка 87
ff2 = freefile ' строка 89
ff3 = freefile ' строка 91
на 1, 2, 3 соответственно.
Я не смог распаковыть архив с примером, поэтому прошу затестить и отписаться.
- Код:
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
ff1= freefile ' строка 87
ff2 = freefile ' строка 89
ff3 = freefile ' строка 91
на 1, 2, 3 соответственно.
Я не смог распаковыть архив с примером, поэтому прошу затестить и отписаться.
а ларчик просто открывался...
Оказалось, причина тормозов была очень и очень проста. Дело в том, что стандартный виндусский cmd.exe не очень быстро выводит текст в консольных приложениях, в отличие от NTVDM. И что вы думаете? Я закомментировал код, отвечающий за вывод значений тайлов на экран, и дебаг-функции, после чего программа стала работать в разы быстрее! Даже быстрее, чем её досовый собрат!
Но я не стал останавливаться на своём QuickBASIC-коде, а взял тот, который написал товарищ trew, за что я и хочу ему выразить огромную человеческую благодарность. Потребовались минимальные штрихи для доведения кода до финального состояния (например, я отключил Screen 1). Но скомпилированная программа и весит меньше (70 кб взамен 89 кб моего кода, скомпилированного в режиме совместимости), и возможностями обладает большими (например, я увеличил стандартный размер массива arrcap до 75000).
Да, думаю, надо уже пересаживаться на FreeBASIC. Может кто-нибудь подсказать хорошие гайды на эту тему? Желательно русскоязычные.
Но я не стал останавливаться на своём QuickBASIC-коде, а взял тот, который написал товарищ trew, за что я и хочу ему выразить огромную человеческую благодарность. Потребовались минимальные штрихи для доведения кода до финального состояния (например, я отключил Screen 1). Но скомпилированная программа и весит меньше (70 кб взамен 89 кб моего кода, скомпилированного в режиме совместимости), и возможностями обладает большими (например, я увеличил стандартный размер массива arrcap до 75000).
Да, думаю, надо уже пересаживаться на FreeBASIC. Может кто-нибудь подсказать хорошие гайды на эту тему? Желательно русскоязычные.
Re: Помогите разобраться с тормозами программы!
ТУТ и ТУТМожет кто-нибудь подсказать хорошие гайды на эту тему? Желательно русскоязычные.
trew- Сообщения : 331
Дата регистрации : 2010-10-14
Re: Помогите разобраться с тормозами программы!
У меня вопрос к Trew: наскоко я понял этот кусок кода:
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 ). И это изменения?! Тогда уж проще вообще убрать этот кусок. или хотя бы поставить его перед(за) циклом( любым ). имхо.
- Код:
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 ). И это изменения?! Тогда уж проще вообще убрать этот кусок. или хотя бы поставить его перед(за) циклом( любым ). имхо.
Re: Помогите разобраться с тормозами программы!
Саня пишет:У меня вопрос к 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: Помогите разобраться с тормозами программы!
В выражении 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?
Re: Помогите разобраться с тормозами программы!
Задача решена, не спорю. насчет скорости. ээмм дело немного субъективно и на разных компах разное покажет. Как я понимю изначальный код был написан давно, но не особо оптимизирован, хотя достточно потратить день-два, имхо. насчет твоего кода. мне не понравилось это решение, потому что хотя на вывод тратится много времени, несравнимо больше, чем на пустое сравнение, но зная в каком месте он будет вызван, что он покажет, можно его перенести в другое место где он не будет требовать сравнений, тем более что это частный случай.
Для всего и всегда может найтись, где ещё улучшить, но не всегда вовремя.
PS: блин, бесит, когда вместо табуляций пробелы.
- Код:
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: блин, бесит, когда вместо табуляций пробелы.
Re: Помогите разобраться с тормозами программы!
Я вообще эти дебаг-функции вместе с указанным IF закомментировал. Так что обсуждать их незачем.
FreeBasic :: Программирование :: Общее
Страница 1 из 1
Права доступа к этому форуму:
Вы не можете отвечать на сообщения
|
|