Jump to content

How to free up memory after using _FileReadToArray


 Share

Go to solution Solved by Jos,

Recommended Posts

I need to read multiple files and run through each line to look for a gap in a time column from one row to another. For this, I use _FileReadToArray then loop through the array since that UDF works far better than FileReadLine. It works fine for the first file or two, but then I get a "Error Allocating Memory" error. If I start from the file it errors on, it works fine then throws an error again a few files later. The files are generally around half a gig with millions of rows.

I have tried to free up memory by setting the array variable to "", using _ArrayDelete, redeclaring the array variable, and _ReduceMemory() from 

Below is a simple test process I've been using to try to figure out how to solve this problem.

#include <File.au3>
#include <Array.au3>


Global $Files[6]


$Files[0] = "D:\Bryan\Applanix test\AutomationTest\Exports\PWL00217_SG\RealTime_PWL00217_SG.txt"
$Files[1] = "D:\Bryan\Applanix test\AutomationTest\Exports\PWL00230_AZ\RealTime_PWL00230_AZ.txt"
$Files[2] = "D:\Bryan\Applanix test\AutomationTest\Exports\PWL00240_AZ\RealTime_PWL00240_AZ.txt"
$Files[3] = "D:\Bryan\Applanix test\AutomationTest\Exports\PWL00217_SG\RealTime_PWL00217_SG.txt"
$Files[4] = "D:\Bryan\Applanix test\AutomationTest\Exports\PWL00230_AZ\RealTime_PWL00230_AZ.txt"
$Files[5] = "D:\Bryan\Applanix test\AutomationTest\Exports\PWL00240_AZ\RealTime_PWL00240_AZ.txt"

For $i = 0 to 5
    wLog($i)
    ;_FileReadToArray($Files[$i],$File)
    $check = Test($Files[$i])
    wLog($check)
Next
wLog("Got here")
Exit

Func Test(ByRef $Path)
    Local $File
    Local $Output
    _FileReadToArray($Path,$File)
    $Output = $File[0]
    ;_ArrayDelete($File,("0-" & $File[0]))
    ;Local $File = ""
    ;$File = ""
    ;_ReduceMemory()
    
    Return $Output
    
EndFunc

If it matters, I am running the script from a .au3 file, not done up as an .exe. 

The only next step I can think of doing is to take the entire function I use to read the files, find the time gaps, and populate a different array accordingly into a seperate .au3 or even a .exe and call it, and have it return the needed gap array. 

 

Any suggestions? Also, if I have to go the seperate code route do I have to publish/compile it fully as an .exe or would puting it in a .au3 and including that cause the memory to free up when it is done?

Link to comment
Share on other sites

  • Developers

Why do you need to read them into an Array first, in stead of processing them one at a time record by record?

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Because whenever I tried FileReadLine checking millions of rows was taking many, many minutes as opposed to _FileReadToArray which was only taking ~20 seconds per file while iterating through the whole thing to find gaps takes less than a second. As I recall that was a known thing with FileReadLine, it gets slower the further into a file you get because it is reading every line before the one you want every time, or at least that is how I recall the description. 
Is there another option I'm not aware of?

 

Link to comment
Share on other sites

  • Developers

Don't think it does that unless you specify the linenumber with a filename. Doing an openfile and then using the returned filehandle in a filereadline till the eof should not do that as far as I know.

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

I agree with Jos.  What taking so much time with FileReadLine is when you DO NOT use file handle.  As for memory consumption, it will be far less than using _FileReadToArray.

Link to comment
Share on other sites

Also AutoIt arrays are capped at 16M cells.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

I am trying to FileReadLine but it is extremely slow. Here is the simple test code I'm using 

For $i = 0 to 5
    wLog($i)
    Test($Files[$i])
Next
Exit

Func Test(ByRef $File)
    Local $FileHandle
    Local $LineNum = 1
    Local $loopCount = 0
    
    $FileHandle = FileOpen($File)
    
    While 1
        $line = FileReadLine($FileHandle,$LineNum)
        if @error = -1 Then ExitLoop
        $loopCount+=1
        if $loopCount > 100 Then
            wLog($LineNum)
            $loopCount = 0
        EndIf
        $LineNum+=100
    WEnd
    
EndFunc

 

Basically I'm just reading every hundred lines and writing to the console every hundred loops which is every 10,000 lines. 

Here is what the is in the console. First 20,000 rows in 3 seconds, but it gets slower the longer it runs.

If this is supposed to be just as quick as reading to array, what am I doing wrong?

image.png.b16829117e1bbffcbaf0640e167b45c4.png

 

 

 

 

Link to comment
Share on other sites

  • Developers
  • Solution

You are still using a linenumber, don't!

try:

For $i = 0 to 5
    wLog($i)
    Test($Files[$i])
Next
Exit

Func Test(ByRef $File)
    Local $FileHandle
    Local $LineNum = 1
    Local $loopCount = 0
    
    $FileHandle = FileOpen($File)
    
    While 1
        $line = FileReadLine($FileHandle)
        if @error Then ExitLoop
        $loopCount+=1
        if $loopCount > 100 Then
            wLog($LineNum)
            $loopCount = 0
        EndIf
        $LineNum+=100
    WEnd
    FileClose($FileHandle)
EndFunc

what does this give?

 

quote from the helpfile: 

Quote

If a filehandle is passed to the function and no line number is specified, the "next" line will be read - for a newly opened file this will be the first line. If lines are read in a loop, it is recommended to let the count increase automatically and not to use the "line" parameter, as doing so will force AutoIt to re-read the file from the beginning each time, significantly slowing execution time for large files.

 

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • Developers

Understood, but it isn't as to know what the line number is, you have to read it from scratch each time! ;) 

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • Developers

by the way: It is also good practice to do a fileclose(FileHandle) after you are done as else the handles will remain open till AutoIt closes.
see updated code I posted.

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • Moderators

BryanWall,

You should see the "edit" menu item now.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...