;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfFileReverseV5 (strFilenameIn, strFilenameOut) intFileSize = FileSize (strFilenameIn) intLast = 1 + intFileSize hdlBB = BinaryAlloc (intLast) intBytesRead = BinaryReadEx (hdlBB, 1, strFilenameIn, 0, intFileSize) intMid = intLast / 2 For intLeft = 1 To intMid intRight = intLast - intLeft BinaryPoke (hdlBB, intLeft - 1, BinaryPeek (hdlBB, intRight)) BinaryPoke (hdlBB, intRight, BinaryPeek (hdlBB, intLeft)) Next BinaryWriteEx (0, 0, strFilenameOut, 0, -1) intBytesWritten = BinaryWriteEx (hdlBB, 0, strFilenameOut, 0, intMid) + BinaryWriteEx (hdlBB, intMid + 1, strFilenameOut, intMid, intLast - intMid - 1) hdlBB = BinaryFree (hdlBB) Return intBytesWritten ;.......................................................................................................................................... ; This UDF "udfFileReverse" reads the content of the given input file ; and writes the same content into the new output file but in reversed order. ; ; Return value is the number of bytes written. ; ; (c)Detlev Dalitz.20100216. ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfFileReverseV4 (strFilenameIn, strFilenameOut) hdlBB = BinaryAlloc (FileSize (strFilenameIn)) intLast = BinaryRead (hdlBB, strFilenameIn) - 1 intMid = (intLast / 2) - !(intLast & 1) For intLeft = 0 To intMid intRight = intLast - intLeft intByte = BinaryPeek (hdlBB, intRight) BinaryPoke (hdlBB, intRight, BinaryPeek (hdlBB, intLeft)) BinaryPoke (hdlBB, intLeft, intByte) Next intBytesWritten = BinaryWrite (hdlBB, strFilenameOut) hdlBB = BinaryFree (hdlBB) Return intBytesWritten ;.......................................................................................................................................... ; This UDF "udfFileReverse" reads the content of the given input file ; and writes the same content into the new output file but in reversed order. ; ; Return value is the number of bytes written. ; ; (c)Detlev Dalitz.20100216. ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfFileReverseV3 (strFilenameIn, strFilenameOut) intFileSize = FileSize (strFilenameIn) intLast = 1 + intFileSize hdlBB = BinaryAlloc (intLast) intBytesRead = BinaryReadEx (hdlBB, 1, strFilenameIn, 0, intFileSize) intMid = intLast / 2 For intLeft = 1 To intMid intRight = intLast - intLeft BinaryPoke (hdlBB, 0, BinaryPeek (hdlBB, intRight)) BinaryPoke (hdlBB, intRight, BinaryPeek (hdlBB, intLeft)) BinaryPoke (hdlBB, intLeft, BinaryPeek (hdlBB, 0)) Next BinaryWriteEx (0, 0, strFilenameOut, 0, -1) intBytesWritten = BinaryWriteEx (hdlBB, 1, strFilenameOut, 0, intFileSize) hdlBB = BinaryFree (hdlBB) Return intBytesWritten ;.......................................................................................................................................... ; This UDF "udfFileReverse" reads the content of the given input file ; and writes the same content into the new output file but in reversed order. ; ; Return value is the number of bytes written. ; ; (c)Detlev Dalitz.20100216. ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfFileReverseV2 (strFilenameIn, strFilenameOut) intFileSize = FileSize (strFilenameIn) hdlBBIn = BinaryAlloc (intFileSize) hdlBBOut = BinaryAlloc (intFileSize) intLast = intFileSize - 1 intBytesRead = BinaryRead (hdlBBIn, strFilenameIn) For intI = 0 To intLast BinaryPoke (hdlBBOut, intLast - intI, BinaryPeek (hdlBBIn, intI)) Next intBytesWritten = BinaryWrite (hdlBBOut, strFilenameOut) hdlBBIn = BinaryFree (hdlBBIn) hdlBBOut = BinaryFree (hdlBBOut) Return intBytesWritten ;.......................................................................................................................................... ; This UDF "udfFileReverse" reads the content of the given input file ; and writes the same content into the new output file but in reversed order. ; ; Return value is the number of bytes written. ; ; (c)Detlev Dalitz.20100216. ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfFileReverseV1 (strFilenameIn, strFilenameOut) arrA = ArrayFromStr (" " : FileGet (strFilenameIn)) intLen = ArrInfo (arrA, 1) intMid = intLen / 2 For intLeft = 1 To intMid intRight = intLen - intLeft arrA[intLeft - 1] = arrA[intRight] arrA[intRight] = arrA[intLeft] Next strString = ArrayToStr (arrA) Return FilePut (strFilenameOut, StrSub (strString, 1, intMid) : StrSub (strString, intMid + 2, intRight)) ;.......................................................................................................................................... ; This UDF "udfFileReverse" reads the content of the given input file ; and writes the same content into the new output file but in reversed order. ; ; Return value is the number of bytes written. ; ; Note: ; Works only with a text file data stream which contain no zero byte. ; ; (c)Detlev Dalitz.20100216. ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ; Test. GoSub FunctionalTest GoSub PerformanceTest Exit ;------------------------------------------------------------------------------------------------------------------------------------------ :FunctionalTest strFileRoot = ItemRemove (-1, IntControl (1004, 0, 0, 0, 0), ".") strFilenameIn = strFileRoot : ".reverse.in.txt" strTest = "1234567890ABCDEFGHIJK" ; 21 chars. intBytesWritten = FilePut (strFilenameIn, strTest) strFilenameOut1 = strFileRoot : ".reverse.out.1.txt" intBytesWritten1 = udfFileReverseV1 (strFilenameIn, strFilenameOut1) strFilenameOut2 = strFileRoot : ".reverse.out.2.txt" intBytesWritten2 = udfFileReverseV2 (strFilenameIn, strFilenameOut2) strFilenameOut3 = strFileRoot : ".reverse.out.3.txt" intBytesWritten3 = udfFileReverseV3 (strFilenameIn, strFilenameOut3) strFilenameOut4 = strFileRoot : ".reverse.out.4.txt" intBytesWritten4 = udfFileReverseV4 (strFilenameIn, strFilenameOut4) strFilenameOut5 = strFileRoot : ".reverse.out.5.txt" intBytesWritten5 = udfFileReverseV5 (strFilenameIn, strFilenameOut5) Run (strFilenameOut1, "") Run (strFilenameOut2, "") Run (strFilenameOut3, "") Run (strFilenameOut4, "") Run (strFilenameOut5, "") Return ; from GoSub. ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ :PerformanceTest ;------------------------------------------------------------------------------------------------------------------------------------------ ; This profiling loop includes five variants of coding algorithms of the "udfFileReverse" function. ;------------------------------------------------------------------------------------------------------------------------------------------ ; Which tests to check. intTestMin = 1 intTestMax = 5 ; How many loops to run. intLoopMax = 4 ; Init for all. ClipPut ("") strFileRoot = ItemRemove (-1, IntControl (1004, 0, 0, 0, 0), ".") strFilenameIn = strFileRoot : ".reverse.in.txt" strFilenameOutMask = strFileRoot : ".reverse.out.{1}.txt" strTest = "1234567890ABCDEFGHIJK" ; 21 chars. ;intBytesWritten = FilePut (strFilenameIn, StrFill (strTest, 20)) ; 20 Bytes. ;intBytesWritten = FilePut (strFilenameIn, StrFill (strTest, 21)) ; 21 Bytes. intBytesWritten = FilePut (strFilenameIn, StrFill (strTest, 10000)) ; 10000 Bytes. ;intBytesWritten = FilePut (strFilenameIn, StrFill (strTest, 100000)) ; 100000 Bytes. ; Loop. BoxOpen ("Performance Test", "Be patient ...") For intTest = intTestMin To intTestMax strFilenameOut = StrReplace (strFilenameOutMask, "{1}", intTest) intTicks%intTest% = 0 For intLoop = 1 To intLoopMax strMsgText = "Test: " : intTestMax : "/" : intTest : @LF : "Loop: " : intLoopMax : "/" : intLoop : @LF : "Ticks%intTest%: " : intTicks%intTest% BoxText (strMsgText) Exclusive (@ON) GoSub Test%intTest% Exclusive (@OFF) intTicks%intTest% = intTicks%intTest% + intTicksStop - intTicksStart Next BoxText (strMsgText) Next BoxShut () ; Result. Decimals (1) intTicksSum = 0 For intTest = intTestMin To intTestMax intTicksSum = intTicksSum + intTicks%intTest% Next If intTicksSum < 1 Then intTicksSum = 1 ; To prevent dividing by zero. For intTest = intTestMin To intTestMax intPct%intTest% = 100.0 * intTicks%intTest% / intTicksSum Next ; Format output; strTest = "Test" strTicks = "Ticks" strPct = "Pct" strSep = " " strPre = "; " intLenTest = Max (StrLen (strTest), StrLen (intTestMax)) intLenTicks = StrLen (strTicks) intLenPct = StrLen (strPct) For intTest = intTestMin To intTestMax intLenTicks = Max (intLenTicks, StrLen (intTicks%intTest%)) intLenPct = Max (intLenPct, StrLen (intPct%intTest%)) Next strTest = StrFixLeft (strTest, " ", intLenTest) strTicks = StrFixLeft (strTicks, " ", intLenTicks) strPct = StrFixLeft (strPct, " ", intLenPct) strResult = "" strResult = ItemInsert (strPre : "Iterations: " : intLoopMax, -1, strResult, @LF) strResult = ItemInsert (strPre : strTest : strSep : strTicks : strSep : strPct, -1, strResult, @LF) For intTest = intTestMin To intTestMax strTest = StrFixLeft (intTest, " ", intLenTest) strTicks = StrFixLeft (intTicks%intTest%, " ", intLenTicks) strPct = StrFixLeft (intPct%intTest%, " ", intLenPct) strResult = ItemInsert (strPre : strTest : strSep : strTicks : strSep : strPct, -1, strResult, @LF) Next strResult = strResult : @LF Message ("Performance Test Result", strResult) ClipPut (strResult) Return ; from GoSub. ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ ; Test GoSub's. ;------------------------------------------------------------------------------------------------------------------------------------------ :Test1 intTicksStart = GetTickCount () intBytesWritten1 = udfFileReverseV1 (strFilenameIn, strFilenameOut) intTicksStop = GetTickCount () Return ; from GoSub. ;------------------------------------------------------------------------------------------------------------------------------------------ :Test2 intTicksStart = GetTickCount () intBytesWritten2 = udfFileReverseV2 (strFilenameIn, strFilenameOut) intTicksStop = GetTickCount () Return ; from GoSub. ;------------------------------------------------------------------------------------------------------------------------------------------ :Test3 intTicksStart = GetTickCount () intBytesWritten3 = udfFileReverseV3 (strFilenameIn, strFilenameOut) intTicksStop = GetTickCount () Return ; from GoSub. ;------------------------------------------------------------------------------------------------------------------------------------------ :Test4 intTicksStart = GetTickCount () intBytesWritten4 = udfFileReverseV4 (strFilenameIn, strFilenameOut) intTicksStop = GetTickCount () Return ; from GoSub. ;------------------------------------------------------------------------------------------------------------------------------------------ :Test5 intTicksStart = GetTickCount () intBytesWritten5 = udfFileReverseV5 (strFilenameIn, strFilenameOut) intTicksStop = GetTickCount () Return ; from GoSub. ;------------------------------------------------------------------------------------------------------------------------------------------ ;========================================================================================================================================== ; Filesize: 10000 Bytes ; Iterations: 20 ; Test Ticks Pct ; 1 33204 12.9 <== The winner (text only). ; 2 52111 20.3 ; 3 65548 25.5 ; 4 55125 21.5 ; 5 50779 19.8 <== The winner (binary). ;------------------------------------------------------------------------------------------------------------------------------------------ ; Filesize: 100000 Bytes ; Iterations: 4 ; Test Ticks Pct ; 1 63592 12.7 <== The winner (text only). ; 2 101375 20.2 ; 3 128859 25.7 ; 4 108439 21.6 ; 5 99483 19.8 <== The winner (binary). ;==========================================================================================================================================