Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

speed up IniWrite


  • Please log in to reply
9 replies to this topic
Tekl
  • Members
  • 814 posts
  • Last active: May 03 2009 03:28 PM
  • Joined: 24 Sep 2004
Hi,

is there a way to speed up IniWrite? It seems that every command will open the ini-file again and if the file is very large a loop with many writes is very slow. I thought of reading the ini once into a varible and using own functions to read/write values and then writing the whole ini to disk. Is it the right thought to improve speed?
Tekl

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
In the code, each IniWrite amounts to a single call to the Windows API function WritePrivateProfileString(). Since this is a built-in OS feature, there's probably not much that can be done to speed it up.

To get more speed, I think your idea is the best approach: load the entire INI file into memory, make all changes, then write the entire file to back out to disk.

Depending on what you want changes you want to make to the INI file, a file-reading/writing loop might also be quite fast.

Tekl
  • Members
  • 814 posts
  • Last active: May 03 2009 03:28 PM
  • Joined: 24 Sep 2004
Hi Chris,

I've made another benchmark to check what's the fastest way manipulating files. The slowest way to do so is using Loop, Read with directly appending to another file. FileRead and Loop, Parse as one tick slower than Loop, Read to a Variable which is written after the loop. IniWrite is in the middle.

here the code I used, I know that's only a proof of concept, because it doesn't handle values with = inside ...
setbatchlines, -1
Process, Priority,, H
;BlockInput, On

FileDelete, FRtest.ini
FileDelete, LRtest.ini
FileDelete, LRFAtest.ini
FileDelete, test.ini
Loop, 10000
{
   Content = %Content%key%A_Index% = this is only a benchmark-test. this loop creates a big file to test the performance of FileRead and Loop`, Read.`r`n
}
FileAppend, [Section]`r`n%Content%, test.ini

numValues = 1000
Loop, %numValues%
{
   If (Mod(A_Index,2) = 0)
   {
      keyIndex++
      ChangeKey[%keyIndex%] = key%A_Index%
      ChangeValue[%keyIndex%] = This is a new value to write to even keys in the ini.
      ChangeSection[%keyIndex%] = section
   }
}


newContent =
actualSection =
Sleep, 200

time = %A_TickCount%
FileRead, Content, test.ini
Loop, Parse, Content, `n, `r
{
   StringSplit, Line, A_LoopField, =
   Line1 = %Line1% ; AutoTrim
   Line2 = %Line2% ; AutoTrim
   IfNotInString, Line2, =
   {
      StringLeft, Line1left, Line1, 1
      StringRight, Line1right, Line1, 1
      If (Line1left = "[" AND Line1right ="]")
      {
         StringTrimLeft, actualSection, Line1, 1
         StringTrimRight, actualSection, actualSection, 1
      }
   }
   Else
   {
      Loop, %numValues%
      {
         If (Line1 = ChangeKey[%A_Index%] AND actualSection = ChangeSection[%A_Index%])
         {
            Line2 := ChangeValue[%A_Index%]
               Break
         }
      }
   }
   newContent = %newContent%%Line1% = %Line2%`r`n
}
FileAppend, %newContent%, FRtest.ini
time1 := A_TickCount - time

newContent =
actualSection =
Sleep, 200

time = %A_TickCount%
Loop, Read, test.ini, LRtest.ini
{
   StringSplit, Line, A_LoopReadLine, =
   Line1 = %Line1% ; AutoTrim
   Line2 = %Line2% ; AutoTrim
   Line1 = %Line1% ; AutoTrim
   Line2 = %Line2% ; AutoTrim
   IfNotInString, Line2, =
   {
      StringLeft, Line1left, Line1, 1
      StringRight, Line1right, Line1, 1
      If (Line1left = "[" AND Line1right ="]")
      {
         StringTrimLeft, actualSection, Line1, 1
         StringTrimRight, actualSection, actualSection, 1
      }
   }
   Else
   {
      Loop, %numValues%
      {
         If (Line1 = ChangeKey[%A_Index%] AND actualSection = ChangeSection[%A_Index%])
         {
            Line2 := ChangeValue[%A_Index%]
               Break
         }
      }
   }
   FileAppend, %Line1% = %Line2%`r`n, LRFAtest.ini
}
time2 := A_TickCount - time

newContent =
actualSection =
Sleep, 200

time = %A_TickCount%
Loop, Read, test.ini
{
   StringSplit, Line, A_LoopReadLine, =
   Line1 = %Line1% ; AutoTrim
   Line2 = %Line2% ; AutoTrim
   IfNotInString, Line2, =
   {
      StringLeft, Line1left, Line1, 1
      StringRight, Line1right, Line1, 1
      If (Line1left = "[" AND Line1right ="]")
      {
         StringTrimLeft, actualSection, Line1, 1
         StringTrimRight, actualSection, actualSection, 1
      }
   }
   Else
   {
      Loop, %numValues%
      {
         If (Line1 = ChangeKey[%A_Index%] AND actualSection = ChangeSection[%A_Index%])
         {
            Line2 := ChangeValue[%A_Index%]
               Break
         }
      }
   }
   newContent = %newContent%%Line1% = %Line2%`r`n
}
FileAppend, %newContent%, LRtest.ini
time3 := A_TickCount - time

newContent =
actualSection =
Sleep, 200

time = %A_TickCount%
Loop, %numValues%
{
   IniWrite, % ChangeValue[%A_Index%], test.ini, section, % ChangeKey[%A_Index%]
}
time4 := A_TickCount - time

;BlockInput, Off

msgbox, FileRead and variable: %time1% `nLoop, Read with FileAppend: %time2% `nLoop, Read with variable: %time3% `nIniWrite: %time4%

Return

Tekl

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
I didn't quite understand which one you said was faster, but here are my results:

FileRead and variable: 791
Loop, Read with FileAppend: 681
Loop, Read with variable: 811
IniWrite: 24325

Tekl
  • Members
  • 814 posts
  • Last active: May 03 2009 03:28 PM
  • Joined: 24 Sep 2004
Hi,

that's very strange. These are my results. It seem's that my drive is quite slow.

FileRead and variable: 1783
Loop, Read with FileAppend: 90971
Loop, Read with variable: 1953
IniWrite: 4446

EDIT: Aargh, that's my virus-scanner who slows down the disk-performance:

FileRead and variable: 1452
Loop, Read with FileAppend: 1302
Loop, Read with variable: 1643
IniWrite: 40068

Hmm... why is now IniWrite so slow?

Virus-scanner on again (NOD32):

FileRead and variable: 1852
Loop, Read with FileAppend: 44844
Loop, Read with variable: 1963
IniWrite: 16583

Strange, after a huge Loop, Read with FileAppend, the IniWrite is reproduceable faster when the virus-scanner is turned on. If I comment out the part with Loop, Read with FileAppend it's slower.
Tekl

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
A bit of a warning that it would render your PC useless for quite a while with no messages and/or progress displayed would have been nice ;) ...

Here are my odd looking results:

FileRead and variable: 1883
Loop, Read with FileAppend: 4271642
Loop, Read with variable: 1612
IniWrite: 187971

Tekl
  • Members
  • 814 posts
  • Last active: May 03 2009 03:28 PM
  • Joined: 24 Sep 2004
Hi,

what's your virus-scanner?
Tekl

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004

Hi,

what's your virus-scanner?

Hi :) ,
AVG Free Edition 7.0.344

CPU usage showed 99 while the script was running the first time... I ended the process the first time but got the same result the second time so I let it run to get the result posted above.

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
With the virus scanner disabled:

FileRead and variable: 1512
Loop, Read with FileAppend: 2363
Loop, Read with variable: 1603
IniWrite: 35040


The script still showed 99 for CPU usage though...

not-logged-in-daonlyfreez
  • Guests
  • Last active:
  • Joined: --
With AntiVir PE on:

FileRead and variable: 500
Loop, Read with FileAppend: 7719
Loop, Read with variable: 500
IniWrite: 16062

With AntiVir PE off:

FileRead and variable: 515
Loop, Read with FileAppend: 1938
Loop, Read with variable: 516
IniWrite: 15969