Hello,

done a new version of functions with a handle instead of an array (and prefix all functions with CM). the script tests files with 3 methods :
- time1 uses ReadProfileString
- time2 uses my own functions CMIniArray, CMReadIniArray, etc...
- time3 uses IniArray, ReadIniArray, etc...

here is the complete code for test (just create a subdir called "test" with inifiles or change the content of $arrInifiles) :
 Code:
break on

$=setoption( "explicit", "on" )

dim $arrInifiles, $inifile, $tmpfile, $size, $ini, $start, $d1, $d2, $d3
dim $arrSections, $arrKeys, $section, $key, $value

$arrInifiles =
    @scriptdir+"\test\file010.ini",
    @scriptdir+"\test\file020.ini",
    @scriptdir+"\test\file030.ini",
    @scriptdir+"\test\file040.ini",
    @scriptdir+"\test\file050.ini",
    @scriptdir+"\test\file060.ini",
    @scriptdir+"\test\file070.ini",
    @scriptdir+"\test\file080.ini",
    @scriptdir+"\test\file090.ini",
    @scriptdir+"\test\file100.ini",
    ""

right( "        size", 8 )
right( "        time1",8 )
right( "        time2",8 )
right( "        time3",8 )
"  filename"
?
for each $inifile in $arrInifiles
    if $inifile
        $tmpfile = @scriptdir+"\"+@ScriptName+".tmp"

        $size = GetFileSize($inifile)

        ;-- read with ReadProfileString --
        $start = @TICKS
        COPY $inifile $tmpfile
        $arrSections = ReadProfileString( $tmpfile, "", "" )
        $arrSections = split($arrSections, chr(10) )
        for each $section in $arrSections
            if $section
                $arrKeys = ReadProfileString( $tmpfile, $section, "" )
                $arrKeys = split($arrKeys, chr(10) )
                for each $key in $arrKeys
                    if $key
                        $value = ReadProfileString( $tmpfile, $section, $key )
                    endif
                next
            endif
        next
        $d1 = @TICKS - $start

        ;-- read with ini functions (version Christophe) --
        $start = @TICKS
        $ini = CMIniArray( $inifile )
        if not @error
            $arrSections = CMINISections($ini)
            for each $section in $arrSections
                $arrKeys = CMINIKeys( $ini, $section )
                for each $key in $arrKeys
                    $value = CMReadIniArray( $ini, $section, $key )
                next
            next
        endif
        $ = CMCloseIniArrayHandle( $ini )
        $d2 = @TICKS - $start

        $ = CMCloseIniArrayHandle( $ini )

        ;-- read with ini functions (version Glenn) --
        $start = @TICKS
        $ini = IniArray( $inifile )
        if not @error
            $arrSections = INISections($ini)
            for each $section in $arrSections
                $arrKeys = INIKeys( $ini, $section )
                for each $key in $arrKeys
                    $value = ReadIniArray( $ini, $section, $key )
                next
            next
        endif
        $d3 = @TICKS - $start

        right( "        "+$size,8 )
        right( "        "+$d1,  8 )
        right( "        "+$d2,  8 )
        right( "        "+$d3,  8 )
        "  "
        $inifile
        ?

        DEL $tmpfile
    endif
next

;-------------------------------------------------------------------------------
; set of function to read in a ini file (version Christophe)
;-------------------------------------------------------------------------------
; internal function
; returned handle is the index of the entry in a global array
; each item in the array is an array of 4 values :
;   entry 0 is a boolean (handle used or not)
;   entry 1 is the name of the ini file
;   entry 2 is the number of sections found in the ini file
;   entry 3 is an array of sections structures
;
; each section structure is an array of 3 values :
;   entry 0 is the name of the section
;   entry 1 is the number of keys in the section
;   entry 2 is an array of keys structures
;
; each key structure is an array of 2 values :
;   entry 0 is the name of the key
;   entry 1 is the value
;-------------------------------------------------------------------------------
function CMGetIniArrayHandle( $inifilename )
    if not IsDeclared( $_IniArrayGlobalHandle )
        ;-- initialize global internal variables --
        global $_IniArrayGlobalHandleNb            $_IniArrayGlobalHandleNb = -1
        global $_IniArrayGlobalHandleInc        $_IniArrayGlobalHandleInc = 32
        global $_IniArrayGlobalHandle[$_IniArrayGlobalHandleInc]
    endif

    dim $i

    for $i = 0 to $_IniArrayGlobalHandleNb
        if ($_IniArrayGlobalHandle[$i][0]=1) and ($_IniArrayGlobalHandle[$i][1]=$inifilename)
            ;-- inifile already loaded : reuse the same handle --
            $CMGetIniArrayHandle = $i
            exit 0
        endif

        if ($_IniArrayGlobalHandle[$i][0]=0)
            ;-- use a free existing handle --
            $_IniArrayGlobalHandle[$i] = 1, $inifilename, 0, ""
            $CMGetIniArrayHandle = $i
            exit 0
        endif
    next

    ;-- use a new handle --
    $_IniArrayGlobalHandleNb = $_IniArrayGlobalHandleNb + 1
    if $_IniArrayGlobalHandleNb > UBound($_IniArrayGlobalHandle)
        redim preserve $_IniArrayGlobalHandle[ UBound($_IniArrayGlobalHandle)+$_IniArrayGlobalHandleInc ]
    endif
    $_IniArrayGlobalHandle[$_IniArrayGlobalHandleNb] = 1, $inifilename, 0, ""

    $CMGetIniArrayHandle = $_IniArrayGlobalHandleNb
endfunction


;-------------------------------------------------------------------------------
; external function
;-------------------------------------------------------------------------------
function CMCloseIniArrayHandle( $inihandle )
    if $inihandle < 0                           exit    endif
    if $inihandle > $_IniArrayGlobalHandleNb    exit    endif

    if $_IniArrayGlobalHandle[$inihandle][0]=1
        if $_IniArrayGlobalHandle[$inihandle][2]>0
            dim $i
            for $i = 0 to UBound( $_IniArrayGlobalHandle[$inihandle][3] )
                $_IniArrayGlobalHandle[$inihandle][3][$i][1] = 0
                $_IniArrayGlobalHandle[$inihandle][3][$i][2] = ""
            next
        endif
        $_IniArrayGlobalHandle[$inihandle] = 0, "", 0, ""
    endif
endfunction


function CMIniArray( $inifilename )
    dim $fHandle                                         ; file pointer

    $CMIniArray = -1
    $fHandle = FreeFileHandle()                          ; locate an available file handle
    if not $fHandle
        exit 1                                           ; none available - exit
    endif

    ;-- try to open file for read into a memory structure --
    if Open($fHandle, $inifilename, 2)<>0                ; open the file for read
        exit 2                                           ; error opening - exit
    endif

    dim $inihandle
    $inihandle = CMGetIniArrayHandle( $inifilename )

    dim $inc        $inc = 128
    dim $arrSections[$inc], $nbSection, $section
    dim $arrKeys[$inc], $nbKey
    dim $_, $ch, $i

    $nbSection    = -1
    do                                                   ; loop through the file contents
        $_ = Trim(ReadLine($fHandle))                    ; remove leading/trailing spaces
        if $_
            $ch = Left($_, 1)
            select
                case $ch="["
                    $ch = Right($_, 1)
                    if $ch="]"                           ; found a section
                        If $nbSection > -1               ; process prior section data, if any
                            gosub _CMIniArray_SavePreviousSection
                        endif

                        $nbKey = -1
                        $nbSection = $nbSection + 1      ; increment the section index
                        if $nbSection > UBound($arrSections)
                            redim Preserve $arrSections[ UBound($arrSections)+$inc ]
                        endif

                        $section = SubStr($_, 2, len($_)-2 )
                    endif

                case $ch=";"                             ; comment line
                case $ch="#"                             ; comment line

                case Len($_) > 2
                    if $nbSection > -1
                        $nbKey = $nbKey + 1
                        if $nbKey > UBound($arrKeys)
                            redim preserve $arrKeys[ UBound($arrKeys)+$inc ]
                        endif

                        $i = instr( $_, "=" )
                        if $i
                            $arrKeys[ $nbKey ] = substr( $_, 1, $i-1), substr( $_, $i+1 )
                        else
                            $arrKeys[ $nbKey ] = $_, ""
                        endif
                    endif

                case 1
            endselect
        endif
    Until @ERROR                                         ; done with input data
    $_ = Close($fHandle)                                 ; close the file

    ;-- process the last/only section --
    If $nbSection > -1
        gosub _CMIniArray_SavePreviousSection

        redim preserve $arrSections[$nbSection]
        $_IniArrayGlobalHandle[$inihandle][2] = $nbsection + 1
        $_IniArrayGlobalHandle[$inihandle][3] = $arrSections
    else
        $_IniArrayGlobalHandle[$inihandle][2] = 0
        $_IniArrayGlobalHandle[$inihandle][3] = ""
    endif

    $CMIniArray = $inihandle                             ; return the array

    Exit 0                                               ; exit success

:_CMIniArray_SavePreviousSection
    if $nbKey=-1
        $arrSections[$nbSection] = $section, 0, ""
    else
        redim preserve $arrKeys[ $nbKey ]
        $arrSections[$nbSection] = $section, ($nbKey+1), $arrKeys
    endif

    return
endfunction


function CMReadIniArray( $inihandle, OPTIONAL $Section, OPTIONAL $Key )
    ;-- in the code --
    ;   $_IniArrayGlobalHandle[$inihandle][2]                     number of sections
    ;   $_IniArrayGlobalHandle[$inihandle][3]                     array of sections
    ;   $_IniArrayGlobalHandle[$inihandle][3][$sectionindex][1]   number of keys in a section
    ;   $_IniArrayGlobalHandle[$inihandle][3][$sectionindex][2]   array of (key, value) in a section
    ;
    ; If the Section is null, return a delimited string of Sections [same as ReadProfileString(file)]
    $CMReadIniArray = ""
    If Not $Section
        if $_IniArrayGlobalHandle[$inihandle][2] > 0
            ;-- enum section name in the inifile --
            for each $section in $_IniArrayGlobalHandle[$inihandle][3]
                $CMReadIniArray = $CMReadIniArray + $section[0] + chr(10)
            next
        endif
        Exit 0
    endif

    ; Search the index for a section
    dim $sectionindex, $i, $item
    $sectionindex = -1
    if $_IniArrayGlobalHandle[$inihandle][2] > 0
        for $i = 0 to UBound($_IniArrayGlobalHandle[$inihandle][3])
            if $_IniArrayGlobalHandle[$inihandle][3][$i][0]=$section
                $sectionindex = $i
            endif
        next
    endif
    If $sectionindex < 0 Exit 2 endif                    ; section not found - Exit

    If Not $Key
        ;-- enum key name in the section --
        if $_IniArrayGlobalHandle[$inihandle][3][$sectionindex][1]<>0
            for each $item in $_IniArrayGlobalHandle[$inihandle][3][$sectionindex][2]
                $CMReadIniArray = $CMReadIniArray + $item[0] + chr(10)
            next
        endif

        Exit 0
    endif

    for each $item in $_IniArrayGlobalHandle[$inihandle][3][$sectionindex][2]
        if $item[0]=$key
            $CMReadIniArray = $item[1]
            exit 0                                       ; key found
        endif
    next

    exit 2                                               ; key not found
endfunction


function CMINISections( $inihandle )
    $CMINISections = CMReadIniArray( $inihandle )
    if Len($CMINISections) > 0
        $CMINISections=split($CMINISections,chr(10))
    endif
endfunction


function CMINIKeys( $inihandle, $section )
    $CMINIKeys = CMReadIniArray( $inihandle, $section )
    if Len($CMINIKeys) > 0
        $CMINIKeys=split($CMINIKeys,chr(10))
    endif
endfunction

;-------------------------------------------------------------------------------
; set of function to read in a ini file (version Glenn)
;-------------------------------------------------------------------------------
;FROM http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Number=202790#Post202790
Function IniArray($_fSrcFile, OPTIONAL $_aDataWrite)
    Dim $_                                    ; temp var
    Dim $_Fp                                ; file pointer
    Dim $_I, $_J                            ; index pointers
    Dim $_Sect                                ; Section Name
    Dim $_aDat                                ; Data pair
    Dim $_aSect[1,0], $_aData[1, 0]            ; Section & Data Arrays


    ; Obtain a File Handle for Read or Write operations
    ; ============================================================
    $_Fp = FreeFileHandle                                ; locate an available file handle
    If Not $_Fp
        Exit 1                                           ; none available - exit
    EndIf


    ; WRITE: verify that we have properly formatted data
    ; ============================================================
    If VarType($_aDataWrite)  > 0                        ; Write the array to the INI file and exit
        If VarType($_aDataWrite) < 8192                  ; data but not an array - exit!
            Exit 87
        EndIf

        Del $_fSrcFile                                   ; delete any pre-existing file
        $_ = Open($_Fp, $_fSrcFile, 5)                   ; open the file for write/create
        If @ERROR Exit @ERROR EndIf                      ; exit if error opening

        ; Write the section data. If no data exists in the section, do not write anything!
        For $_I = 0 to UBound($_aDataWrite, 2)
            $_Sect  = $_aDataWrite[0, $_I]               ; Section name to write
            $_aData = $_aDataWrite[1, $_I]               ; Data array
            If UBound($_aData, 2) > -1                   ; create Sect and write data if data is present
                $_ = '[' + $_Sect + ']' + @CRLF          ; section name
                For $_J = 0 to UBound($_aData, 2)        ; key/data pairs
                    If $_aData[1, $_J]                   ; only write keys that have non-null data
                        $_ = $_ + $_aData[0, $_J] + '=' + $_aData[1, $_J] + @CRLF
                    EndIf
                Next
                $_ = WriteLine($_Fp, $_)                 ; write the output line
                If @ERROR Exit @ERROR EndIf              ; exit if error writing
            EndIf
        Next

        $_ = Close($_Fp)                                 ; close the file
        ReDim $_aData[1, 0]                              ; clear array

        ; exit 0 ; do not exit here to force a re-read of the freshly written data
    EndIf


    ; READ: Load the ini file into an array
    ; ============================================================
    $_I = -1  $_J = -1                                   ; Initialize index pointers

    $_ = Open($_Fp, $_fSrcFile, 2)                       ; open the file for read
    If @ERROR Exit @ERROR EndIf                          ; exit if error opening

    Do                        ; loop through the file contents
        $_ = Trim(ReadLine($_Fp))                        ; remove leading/trailing spaces

        If Left($_, 1) = '['                             ; found a section

            If $_I >= 0                                  ; process prior section data, if any
                $_aSect[1, $_I] = $_aData
                ReDim $_aData[1, 0]
                $_J = -1
            EndIf

            $_I = $_I + 1                                ; increment the section index
            ReDim Preserve $_aSect[1, $_I]
            $_aSect[0, $_I] = Split(SubStr($_, 2), ']')[0]
        Else
            If Not Left($_, 1) = ';' And Not Left($_, 1) = '#' And Len($_) > 2
                $_aDat = Split($_, '=')                  ; break into array
                $_J = $_J + 1                            ; increment the data index
                ReDim Preserve $_aData[1, $_J]
                $_aData[0, $_J] = $_aDat[0]              ; Store the data
                $_aData[1, $_J] = $_aDat[1]              ; Store the data
            EndIf
        EndIf
    Until @ERROR                                         ; done with input data
    $_ = Close($_Fp)                                     ; close the file

    ; process the last/only section
    If $_I >= 0
        $_aSect[1, $_I] = $_aData
    EndIf

    $IniArray = $_aSect                                  ; return the array

    Exit 0                                               ; exit success
EndFunction


Function ReadIniArray($_aIniFile, OPTIONAL $_Section, OPTIONAL $_Key)
    ; exit immediately if the data format is invalid
    If VarType($_aIniFile) < 8192                        ; data but not an array - exit!
        Exit 87
    EndIf

    Dim $_aSectIdx[UBound($_aIniFile, 2)]                ; Section Index Array
    Dim $_I, $_J                                         ; Index pointers
    Dim $_aData                                          ; Array of Key/Data pairs

    ; Create a section index array
    For $_I = 0 to UBound($_aIniFile, 2)
        $_aSectIdx[$_I] = $_aIniFile[0, $_I]
    Next

    ; If the Section is null, return a delimited string of Sections [same as ReadProfileString(file)]
    If Not $_Section
        $ReadIniArray = Join($_aSectIdx, Chr(10))
        Exit 0
    EndIf

    ; Search the index for a section
    $_I = aScan($_aSectIdx, $_Section)
    If $_I < 0 Exit 2 EndIf                              ; section not found - Exit

    $_aData = $_aIniFile[1, $_I]                         ; Extract the key/value array

    ; Create a Key index for the requested section
    Dim $_aKeyIdx[UBound($_aData, 2)]
    For $_J = 0 to UBound($_aData, 2)
        $_aKeyIdx[$_J] = $_aData[0, $_J]
    Next

    ; If the Key is null, return a delimited string of Keys [same as ReadProfileString(file, section)]
    If Not $_Key
        $ReadIniArray = Join($_aKeyIdx, Chr(10))
        Exit 0
    EndIf

    ; Search the index for a Key
    $_J = aScan($_aKeyIdx, $_Key)
    If $_J < 0 Exit 2 EndIf                              ; Key not found

    $ReadIniArray = $_aData[1, $_J]

    Exit 0
EndFunction



;Modified FROM http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Number=203126#Post203126
function INISections($array)
    $INISections = readiniarray($array)
    if LEN($INISections) > 0
        $INISections=split($INISections,chr(10))
    endif
endfunction

function INIKeys($array,$section)
    $INIKeys = readiniarray($array,$section)
    if LEN($INIKeys) > 0
        $INIKeys=split($INIKeys,chr(10))
    endif
endfunction
.
On a Intel E5200 (Dual-Core 2.5Ghz) with 2Gb, the results are :
 Code:
    size   time1   time2   time3  filename
      91      15       0       0  .\test\file010.ini
    2019       0      16       0  .\test\file020.ini
    7553      16      47      46  .\test\file030.ini
   15173      94    1110    2484  .\test\file040.ini
   28149     187    1704    2296  .\test\file050.ini
   34527      47     250     500  .\test\file060.ini
   43179      94    1031    1938  .\test\file070.ini
   69058     125     515    1125  .\test\file080.ini
  103587     235     797    1922  .\test\file090.ini
  138116     375    1062    2969  .\test\file100.ini

On a Intel Pentium 4 (Mono-Core 2.4Ghz) with 1Gb, the results are :
 Code:
    size   time1   time2   time3  filename
      91       0       0       0  .\test\file010.ini
    2019      15      16      16  .\test\file020.ini
    7553      31      94      93  .\test\file030.ini
   15173     203    2563    6094  .\test\file040.ini
   28149     468    3625    6250  .\test\file050.ini
   34527     125     610    1328  .\test\file060.ini
   43179     218    2532    5015  .\test\file070.ini
   69058     360    1281    3281  .\test\file080.ini
  103587     781    1938    5969  .\test\file090.ini
  138116    1328    2562    9641  .\test\file100.ini

ReadProfileString is always the faster with local file !!!

I use a global array to allocate handle (with associated data). redim is automatic if many differents ini files are used.
I have not tested all cases for CMReadIniArray and I suppress the optional parameter for write in CMIniArray.
Code is not very easy to read because of use of array of array of array ... but it seems to be fast.

Not sure i'll use it in my login script because all procedures are already written to copy inifile locally before using ReadProfileString and delete temp file when finished.
But it was a good exercize for fun ;\)
_________________________
Christophe