Author Topic: Dynamic arrays  (Read 417 times)

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9686
  • Assembler is fun ;-)
    • MasmBasic
Dynamic arrays
« on: July 16, 2019, 11:12:46 AM »
This example reads a text file that has the format Country   Series    Value1  Value 2 into a numeric matrix, i.e. a two-dimensional numeric array - useful for working with spreadsheets and tables. Project attached, MasmBasic of 16 July 2019 or later is required.

include \masm32\MasmBasic\MasmBasic.inc
  Init                                ; *** read values from a text file into a numeric array ***
  Recall "UnderFiveMortalityRate.tab", L$(), tab        ; tab-delimited text -> two-dimensional string array
  Clr ecx, edi                                          ; we need two counters
  Print "Under 5 mortality rate", CrLf$, L$(0, 0)       ; Country
  Print At(22) "  ", L$(0, 2), Tb$, L$(0, 3)            ; 1990, 2013
  QSort L$(), 0, 2003h                ; sort string array numerically by column 3
  Delete L$(0)                        ; we don't want the captions
  Dim Under5() As double              ; create a dynamic numeric array
  Dim StringIndex() As DWORD          ; and another one to keep track of the names
  .Repeat
        xor esi, esi                  ; column counter
        .Repeat
                MovVal <Under5(edi, esi)>, L$(ecx, esi+2)    ; assign values to the numeric array
                inc esi
        .Until edx==-127 || esi>=99     ; MovVal returns -127 in edx if no valid number was found
        .if esi>2
                mov StringIndex(edi), ecx       ; remember the country
                inc edi         ; advance numeric array row index only if at least two values found
        .endif
        inc ecx
  .Until ecx>=L$(?)             ; loop until strings are finished
  For_ ct=0 To Under5(?rows)-1
                Print Str$("\n%i\t", ct), L$(StringIndex(ct), 0)
                Print At(22) " "
                For_ ecx=0 To Under5(?cols)-1
                                Print Tb$, Str$("%4f", Under5(ct, ecx))
                Next
  Next
  PrintLine CrLf$
  deb 4, "total strings", L$(?)
  deb 4, "total numbers", Under5(?)
  deb 4, "valid rows", Under5(?rows)
  deb 4, "valid columns", Under5(?cols)
  Inkey "--- hit any key ---"
EndOfCode


Output:
Code: [Select]
Under 5 mortality rate
Country                 1990    2013
0       Iceland         6.400   2.100
1       Finland         6.700   2.600
2       Singapore       7.700   2.800
3       Sweden          6.900   3.000
4       Italy           9.600   3.600
5       Austria         9.500   3.900
6       Germany         8.500   3.900
7       Australia       9.200   4.000
8       France          9.000   4.200
9       Switzerland     8.200   4.200
10      Belgium         10.000  4.400
11      United Kingdom  9.300   4.600
12      Cuba            13.30   6.200
13      United States   11.20   6.900
14      Yemen           124.8   51.30
15      Zambia          192.5   87.40
16      Zimbabwe        74.60   88.50
17      Afghanistan     179.1   97.30

total strings   eaX             23
total numbers   eax             36
valid rows      eax             18
valid columns   eax             2

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9686
  • Assembler is fun ;-)
    • MasmBasic
Case-sensitive vs case-insensitive sorting of text arrays
« Reply #1 on: August 12, 2019, 08:18:46 PM »
This snippet (source & exe attached) compares the time needed to sort a text array in case-sensitive vs case-insensitive mode. On my cpu, sorting case-insensitive is roughly a factor 2.5 slower, if somebody has a better algo, I'd like to know about it:

include \masm32\MasmBasic\MasmBasic.inc         ; download
  Init
  PrintCpu 0
  Recall "SortTemp.txt", L$()   ; any text file will do
  NanoTimer()
  QSort L$()
  PrintLine Str$("\nsorting %i lines case-insensitive took ", L$(?)), NanoTimer$()
  For_ ecx=0 To L$(?)-1
        sub L$(?), 3
        .if ecx<3 || ecx>=eax
                .if Zero?
                                PrintLine "..."
                .endif
                PrintLine L$(ecx)
        .endif
  Next
  Print
  Recall "SortTemp.txt", L$()
  NanoTimer()
  QSortMode 0                           ; force case-sensitive sort
  QSort L$()
  PrintLine Str$("sorting %i lines case-sensitive took ", L$(?)), NanoTimer$()
  For_ ecx=0 To L$(?)-1
        sub L$(?), 3
        .if ecx<3 || ecx>=eax
                .if Zero?
                                PrintLine "..."
                .endif
                PrintLine L$(ecx)
        .endif
  Next
EndOfCode


Results for an array of random strings:
Code: [Select]
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz

sorting 1000000 lines case-insensitive took 1434 ms
AAaAHZybMJfIBMDPTlGpjvUIKUAUarYYBhwoQzXDbBiAcpCJBdWibuPGKXCeSrAcOsQVouKGLUtXF
aAABoYraUmtdbUjgRDbugWslpjAUIKuszBiOYgbGgDwawBsyfUTodDuktDyLUCdtDSYqIFfwxoBlKDfbiuHQ
aaadeaEoIYWvHUzkSOtliXprvQLwLRmQtZnACEWprRsosQEBCExqPRkIFHyxbkWHovUZtDOKw
...
ZZzyzetRGgWITClgQOTutTCdCiuHMxPNPuxGIsUFqStMIuIRPqlWpHdzyckcajQMCgNTbYzilNuy
zzZzcsrZGTHbiajufJIMXwWdbKFncznEBmlSLCGJBKFTHoixDzzNgeXSRohyfJHAQreI
zZZzToOoFStspcNrVaEIfjsxTNFZWUIwVWqxrzppJBjnxhbFgXmoCjUQxitzjpsLsmkTJefTDsKUKDj

sorting 1000000 lines case-sensitive took 582 ms
AAAJkbfOkQBObDHcbTIwHpqfZhoeEAOdznaOpVJqBwanparynNfGQbaMfZwqeWVzuereGocrnKWbAx
AAAKDBqCLIvtYhNOwRHDkUdYhtCnqVlAtRxBIyOmZtyRTJmmduoLcogeGKDYzS
AAANyurgtXuGMSDjUiphJpjDEIXsqWblivOefMURODFFRLEmyNHboCtnRgrrGsTpQXBZ
...
zzzMNTYBXQesyiSPhDSnEMllmqJyPOetjQASwTjPPdMGALxaTsXIBwpiDnRqaG
zzzWKRnlAPdJrfgIgiHjbJTvoMgrRnxVAukqhhjMqshOgVAuaGceqItZADoDlNBtykFZjwKyKuMhTJeu
zzzYZAgWBUtSZfUmlAWnFFRpDcGgwdOFndrhSJZcyMsgkvLnTOTRmUtwjKvNKJndDYagMFDBnZQduJzTADOTbIsyx

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 9686
  • Assembler is fun ;-)
    • MasmBasic
Fast and powerful string sort
« Reply #2 on: August 20, 2019, 09:25:54 AM »
The new MasmBasic version of 20 August 2019 features an improved sort algo. Case-sensitive sorts are now over 20% faster, case-insensitive sorting is now almost a factor 3 faster.
Code: [Select]
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz

sorting 1000000 lines case-insensitive took 504 ms
AAaAHZybMJfIBMDPTlGpjvUIKUAUarYYBhwoQzXDbBiAcpCJBdWibuPGKXCeSrAcOsQVouKGLUtXF
aAABoYraUmtdbUjgRDbugWslpjAUIKuszBiOYgbGgDwawBsyfUTodDuktDyLUCdtDSYqIFfwxoBlKDfbiuHQ
aaadeaEoIYWvHUzkSOtliXprvQLwLRmQtZnACEWprRsosQEBCExqPRkIFHyxbkWHovUZtDOKw
...
ZZzyzetRGgWITClgQOTutTCdCiuHMxPNPuxGIsUFqStMIuIRPqlWpHdzyckcajQMCgNTbYzilNuy
zzZzcsrZGTHbiajufJIMXwWdbKFncznEBmlSLCGJBKFTHoixDzzNgeXSRohyfJHAQreI
zZZzToOoFStspcNrVaEIfjsxTNFZWUIwVWqxrzppJBjnxhbFgXmoCjUQxitzjpsLsmkTJefTDsKUKDj

sorting 1000000 lines case-sensitive took 444 ms
AAAJkbfOkQBObDHcbTIwHpqfZhoeEAOdznaOpVJqBwanparynNfGQbaMfZwqeWVzuereGocrnKWbAx
AAAKDBqCLIvtYhNOwRHDkUdYhtCnqVlAtRxBIyOmZtyRTJmmduoLcogeGKDYzS
AAANyurgtXuGMSDjUiphJpjDEIXsqWblivOefMURODFFRLEmyNHboCtnRgrrGsTpQXBZ
...
zzzMNTYBXQesyiSPhDSnEMllmqJyPOetjQASwTjPPdMGALxaTsXIBwpiDnRqaG
zzzWKRnlAPdJrfgIgiHjbJTvoMgrRnxVAukqhhjMqshOgVAuaGceqItZADoDlNBtykFZjwKyKuMhTJeu
zzzYZAgWBUtSZfUmlAWnFFRpDcGgwdOFndrhSJZcyMsgkvLnTOTRmUtwjKvNKJndDYagMFDBnZQduJzTADOTbIsyx