#131956 - 2005-01-05 10:37 AM
Kix script give high cpu usage
|
jan
Getting the hang of it
Registered: 2004-07-07
Posts: 66
|
Hi,
I've made a KIX script that reads a txt-file and the txt-file is only 800KB. When I run the script on my server it has 100% CPU usage. Is there any way I can run the script with low CPU usages/set priority
Jan
PS The script look like this:
FUNCTION READFILE($_file,optional $_delim,optional $_amount) DIM $
$=$_file $_delim=""+$_delim $_amount=0+$_amount $_file=FREEFILEHANDLE() IF 0=$_file EXIT 1 ENDIF IF OPEN($_file,$) EXIT 2 ENDIF $="" DO $=$+READLINE($_file)+CHR(10) UNTIL @error $ReadFile=SPLIT(LEFT($,LEN($)-2),CHR(10)) $=CLOSE($_file) $=""
IF $_amount<0 FOR $_file=$_amount+UBOUND($ReadFile)+1 TO UBOUND($ReadFile) $=$+$ReadFile[$_file]+CHR(10) NEXT $ReadFile=SPLIT(LEFT($,LEN($)-1),CHR(10)) ENDIF
IF $_amount>0 FOR $_file=0 TO $_amount-1 $=$+$ReadFile[$_file]+CHR(10) NEXT $ReadFile=SPLIT(LEFT($,LEN($)-1),CHR(10)) ENDIF
IF $_delim $ReadFile=JOIN($ReadFile,$_delim) ENDIF EXIT 0
ENDFUNCTION
FUNCTION GET_AVG
DIM $x $z $y $line $lines $min
$min=403 $x = "Pooled Available:"
FOR EACH $line IN ReadFile($log,,) $array = $line+@CRLF IF INSTR($array,$x) <> 0 $y = RIGHT($array,5) $y = VAL($y) $sum = $sum + $y $lines = $lines + 1 IF $max < $y $max = $y ENDIF IF $min => $y $min = $y ENDIF
ENDIF NEXT $avg = $sum / $lines
ENDFUNCTION
FUNCTION ADD2LOG
SHELL '%comspec% /c clicense connections > $file'
FOR EACH $line IN ReadFile($file,,22) $array=$array+$line+@CRLF NEXT $InUse= SUBSTR($array,332,500) IF @error "error @error" ENDIF
ENDFUNCTION
;====== Main program
$file="\\dkbirfs01\q8logon$\Scripts\screendump.log" $log="\\dkbirfs01\q8logon$\Scripts\ctxcount.log" ;$log="h:\Scripts\ctxcount.log" ; just for testing
GET_AVG ADD2LOG
REDIRECTOUTPUT($log,0) "@CRLF***********************************@CRLF" "Started Date: @DATE Time: @TIME@CRLF"
"$InUse" "@CRLFAVG licenses available: $avg@CRLF" "MIN licenses available: $min@CRLF" "MAX licenses available: $max@CRLF"
|
Top
|
|
|
|
#131957 - 2005-01-05 10:44 AM
Re: Kix script give high cpu usage
|
Radimus
Moderator
   
Registered: 2000-01-06
Posts: 5187
Loc: Tampa, FL
|
the reason you probably have 100 cpu is you have a runaway code...
there is probably a faw in some loop that is trapping the code and is making it stuck in some endless loop
If it wasn't 4:30 in the morning, I'd look closer at it, but I'm having a hard time focusing on the screen
|
Top
|
|
|
|
#131959 - 2005-01-05 11:52 AM
Re: Kix script give high cpu usage
|
jan
Getting the hang of it
Registered: 2004-07-07
Posts: 66
|
Hi,
The scripts runs for about 15 min and finished perfectly, so I don't think it's a running loop
Jan
|
Top
|
|
|
|
#131960 - 2005-01-05 11:57 AM
Re: Kix script give high cpu usage
|
jan
Getting the hang of it
Registered: 2004-07-07
Posts: 66
|
Hi,
Thanks for your reply. I'll try to use the OPEN/READ instead.
Jan
|
Top
|
|
|
|
#131961 - 2005-01-05 03:01 PM
Re: Kix script give high cpu usage
|
Bryce
KiX Supporter
   
Registered: 2000-02-29
Posts: 3167
Loc: Houston TX
|
Actualy his readfile() UDF is using the OPEN() and Readline() commands... so i doubt that the CPU usage will drop when dealing with such a LARGE file.
You might want to give the WSH file read utils a try.... something like this...
Code:
;this Function will load the contents of a text file into an array Function loadfile($file) DIM $fso,$f,$fs $fso = CreateObject("Scripting.FileSystemObject") $f = $fso.GetFile($file) If @ERROR Exit(2) EndIf $fs = $f.OpenAsTextStream(1) $loadfile = Split($fs.Read($f.size),@CRLF) Exit(@ERROR) EndFunction
Bryce
|
Top
|
|
|
|
#131962 - 2005-01-05 03:21 PM
Re: Kix script give high cpu usage
|
jan
Getting the hang of it
Registered: 2004-07-07
Posts: 66
|
Hi,
just tried your code and it works like a charm. From running in 10-15 min it now only run for 30 sec.
You are me hero 
Jan
|
Top
|
|
|
|
#131963 - 2005-01-05 03:45 PM
Re: Kix script give high cpu usage
|
Richard H.
Administrator
   
Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
|
Quote:
Actualy his readfile() UDF is using the OPEN() and Readline() commands... so i doubt that the CPU usage will drop when dealing with such a LARGE file.
No, that's not correct. Look at the udf more closely, and you will see the obvious problems.
To elaborate, there are two major inefficiencies in the ReadFile() udf.
The most obvious is where you specify a postive limit on the number of lines to be returned. In this case the entire file is read before the code checks to see if there is a limit. This means that if you need the first 10 lines from your 10,000 line file all 10,000 lines will be read anyway.
The second less obvious problem is how ReadFile() manipulates the data.
As each line is read from the file buffer, it is catenated to the end of a string. This string gets longer and longer until it eventually becomes the size of your file. As you can imagine, string manipulations on data this size become slower as the string gets larger, and with a 800KB text file there is likely to be a large number of iterations of the ReadLine() loop.
The string is then converted to an array - again this is not a trivial task for a string of this length.
All this string manipulation occurs in core memory and requires repeated creation and destruction of temporary variable / stack space in the scripts private process space.
The string maniplation is where the majority CPU cycles are burned, not on the file IO.
The reason for moving the ReadLine() activity to the main script is that the temporary string is not created so we lose the massive overhead. As we need to iterate the result anyway we also save the overhead of the do..until loop in the UDF.
However, FSO is a good option too. In this case even with the Split() it may well be quicker than using KiXtart file IO
[edit]
Contribution to the Secret Long Line Policemans ball to follow...
[/edit]
Edited by Richard H. (2005-01-06 09:15 AM)
|
Top
|
|
|
|
#131965 - 2005-01-05 05:00 PM
Re: Kix script give high cpu usage
|
Bryce
KiX Supporter
   
Registered: 2000-02-29
Posts: 3167
Loc: Houston TX
|
Richard,
I will admit i didn't fully process his code before making my post. I looked at it enough to see the readline() loop and knew from personal experience that my bit of FSO code would handle a large file a lot better than any readline() solution.
When i first saw the use of a readfile() UDF in Jan's code I was assuming it was this UDF. ReadFile() (by Radimus), but i see now that we have 2 ReadFile() (by Jooel) UDF's in the UDF forum.
Looks like Jan is using Jooel's version.
|
Top
|
|
|
|
#131966 - 2005-01-05 05:01 PM
Re: Kix script give high cpu usage
|
Bryce
KiX Supporter
   
Registered: 2000-02-29
Posts: 3167
Loc: Houston TX
|
Quote:
Nice code Bryce, except for the use of parens to force precedence on the Exit parm where none is needed.
I wrote that back before the EXIT police started their crack down.....
|
Top
|
|
|
|
#131967 - 2005-01-05 05:03 PM
Re: Kix script give high cpu usage
|
Bryce
KiX Supporter
   
Registered: 2000-02-29
Posts: 3167
Loc: Houston TX
|
actualy need to fine richard for using the "code" tags in place of the "quote" tages and causing a long line
|
Top
|
|
|
|
#131968 - 2005-01-06 02:18 AM
Re: Kix script give high cpu usage
|
kholm
Korg Regular
   
Registered: 2000-06-19
Posts: 714
Loc: Randers, Denmark
|
Just to check the performance of ReDim i made the following function.
It uses only KiX (No COM-objects)
It seems to be faster than Bryce's LoadFile()
Code:
Function ReadFile($file)
Dim $i,$f,$L
$f = FreeFileHandle
$i = Open($f,$file)
If @Error
Exit @Error
EndIf
$i = 0
$L = ReadLine($f)
While @Error = 0
ReDim Preserve $ReadFile[$i]
$ReadFile[$i] = $L
$i = $i + 1
$L = ReadLine($f)
Loop
$i = Close($f)
Exit VarType($ReadFile) = 0 ; Exitcode 1 if file is empty
EndFunction
Small code is not allways the fastest
In many other situations we might consider using the force of KiX.
This could be a starter for a new thread on performans of KiX for long strings, Split, Join and Redim Of arrays and ...
-Erik
|
Top
|
|
|
|
#131969 - 2005-01-06 03:08 AM
Re: Kix script give high cpu usage
|
Bryce
KiX Supporter
   
Registered: 2000-02-29
Posts: 3167
Loc: Houston TX
|
faster.... I dont know....... 
Code:
$start = cdbl(""+flipctime(@date,@time)+"."+@msecs) $file = loadfile("dir.txt") $end = cdbl(""+flipctime(@date,@time)+"."+@msecs) ? "Loadfile() = " $end - $start
$start = cdbl(""+flipctime(@date,@time)+"."+@msecs) $file = readfile("dir.txt") $end = cdbl(""+flipctime(@date,@time)+"."+@msecs) ? "ReadFile() = " $end - $start
Function ReadFile($file) Dim $i,$f,$L $f = FreeFileHandle $i = Open($f,$file) If @Error Exit @Error EndIf $i = 0 $L = ReadLine($f) While @Error = 0 ReDim Preserve $ReadFile[$i] $ReadFile[$i] = $L $i = $i + 1 $L = ReadLine($f) Loop $i = Close($f) Exit VarType($ReadFile) = 0 ; Exitcode 1 if file is empty EndFunction
;this Function will load the contents of a text file into an array Function loadfile($file) DIM $fso,$f,$fs $fso = CreateObject("Scripting.FileSystemObject") $f = $fso.GetFile($file) If @ERROR Exit(2) EndIf $fs = $f.OpenAsTextStream(1) $loadfile = Split($fs.Read($f.size),@CRLF) Exit(@ERROR) EndFunction
Function FlipcTime($date,$time,optional $tz) dim $y,$m,$d $date = split($date,"/") if ubound($date) <> 2 exit(1) endif $y=val($date[0]) $m=val($date[1]) $d=val($date[2]) if $m<3 $m=$m+12 $y=$y-1 endif $Date=$d+(153*$m-457)/5+365*$y+$y/4-$y/100+$y/400-306 $time = split($time,":") select case ubound($time)=1 redim preserve $time[2] $time[2]=0 case ubound($time)=2 case 1 exit(1) endselect $time = (val($time[0])*3600)+(val($time[1])*60)+val($time[2]) $flipctime = IIF($tz,(($date-719163)*86400 + $time)-($tz*3600),($date-719163)*86400 + $time) endfunction
dir.txt is a "dir c:\ /s > dir.txt" and is a file that is 3.9m in size.
this is the results for time in seconds... I ran the above script 5 times in a row Code:
C:\temp>kix32 readfile.kix
Loadfile() = 0.75 ReadFile() = 1.42199993133545 C:\temp>kix32 readfile.kix
Loadfile() = 0.75 ReadFile() = 1.42200016975403 C:\temp>kix32 readfile.kix
Loadfile() = 0.75 ReadFile() = 2.12400007247925 C:\temp>kix32 readfile.kix
Loadfile() = 0.765000104904175 ReadFile() = 1.42199993133545 C:\temp>kix32 readfile.kix
Loadfile() = 0.766000032424927 ReadFile() = 1.42199993133545 C:\temp>
Bryce
|
Top
|
|
|
|
#131971 - 2005-01-06 03:34 PM
Re: Kix script give high cpu usage
|
ChristopheM
Hey THIS is FUN
   
Registered: 2002-05-13
Posts: 309
Loc: STRASBOURG, France
|
I did some modifications to Bryce's source code and the results are a bit differents : Code:
break on
dim $start, $arrInc, $inc, $file
$arrInc = 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192
for each $inc in $arrInc dim $file
$start=@TICKS $file = "" $file = loadfile("dir.txt") $file = "" ? "Loadfile() = " @TICKS - $start
chr(9)
$start=@TICKS $file = "" $file = readfile("dir.txt", $inc, 0) $file = ""
"constant increment ReadFile("+$inc+") = " @TICKS - $start
chr(9)
$start=@TICKS $file = "" $file = readfile("dir.txt", $inc, 1) $file = ""
"variable increment ReadFile("+$inc+") = " @TICKS - $start next ? exit
; will load the contents of a text file into an array only with Kix Function ReadFile($file, optional $inc, optional $incvariable ) Dim $, $i,$f,$L, $j
if not $inc $inc = 1 endif
Dim $ReadFile[$inc]
$f = FreeFileHandle() $ = Open($f,$file) if @Error Exit @Error endIf
$i = -1 $j = 0 $L = ReadLine($f) While not @Error $i = $i + 1 if $i > $j $j = $j + $inc ReDim Preserve $ReadFile[$j] if $incvariable $inc = $inc + $inc endif endif $ReadFile[$i] = $L $L = ReadLine($f) Loop $ = Close($f) if $i=-1 $ReadFile = "" exit 1 else redim preserve $ReadFile[$i] exit 0 endif EndFunction
; will load the contents of a text file into an array with WScript Function loadfile($file) DIM $, $fso,$f,$fs $fso = CreateObject("Scripting.FileSystemObject") $f = $fso.GetFile($file) If @ERROR Exit(2) EndIf $fs = $f.OpenAsTextStream(1) $loadfile = Split($fs.Read($f.size),@CRLF) $ = $f.Close Exit(@ERROR) EndFunction
the results (in ms) are : Code:
Loadfile() = 961 constant increment ReadFile(1) = 1482 variable increment ReadFile(1) = 651 Loadfile() = 1042 constant increment ReadFile(2) = 1372 variable increment ReadFile(2) = 671 Loadfile() = 1091 constant increment ReadFile(4) = 1282 variable increment ReadFile(4) = 671 Loadfile() = 1142 constant increment ReadFile(8) = 1201 variable increment ReadFile(8) = 691 Loadfile() = 1232 constant increment ReadFile(16) = 1122 variable increment ReadFile(16) = 741 Loadfile() = 1272 constant increment ReadFile(32) = 1191 variable increment ReadFile(32) = 731 Loadfile() = 1262 constant increment ReadFile(64) = 1042 variable increment ReadFile(64) = 741 Loadfile() = 1262 constant increment ReadFile(128) = 961 variable increment ReadFile(128) = 761 Loadfile() = 1272 constant increment ReadFile(256) = 821 variable increment ReadFile(256) = 731 Loadfile() = 1352 constant increment ReadFile(512) = 791 variable increment ReadFile(512) = 741 Loadfile() = 1292 constant increment ReadFile(1024) = 771 variable increment ReadFile(1024) = 731 Loadfile() = 1282 constant increment ReadFile(2048) = 751 variable increment ReadFile(2048) = 741 Loadfile() = 1242 constant increment ReadFile(4096) = 801 variable increment ReadFile(4096) = 761 Loadfile() = 1342 constant increment ReadFile(8192) = 842 variable increment ReadFile(8192) = 761
it's surprising because time for LoadFile should be constant and it is not.
"constant increment" means that when i redim an array, i add a constant value to the current size. "variable increment" means that when i redim an array, i add a value to the current size and then, i multiply this value by 2 for the next resizing. I am working on a Pentium IV 2 Mhz with 512 MB. The OS is Windows NT 4 SP6a
PS : sorry for my english
_________________________
Christophe
|
Top
|
|
|
|
#131972 - 2005-01-06 05:49 PM
Re: Kix script give high cpu usage
|
Bryce
KiX Supporter
   
Registered: 2000-02-29
Posts: 3167
Loc: Houston TX
|
We have 2 different readfiles here...
something is wrong with the readfile() that Christophe is using. His readfile it is not returning any information.
ok, i found the error in Chris's readfile() in line 6 in the UDF you need to change the line Code:
Dim $ReadFile[$inc]
to
reDim $ReadFile[$inc]
after doing that... i reran his code (i changed the location of dir.txt to c:\dir.txt, also changing the CI and VI stuff to better fit the screen).
Processor: Intel(R) Pentium(R) 4 CPU 2.66GHz Memory: 510MB RAM
Code:
getfilesize(c:\dir.txt)=7725170 Loadfile() = 2391 CI ReadFile(1) = 6890 VI ReadFile(1) = 2781 Loadfile() = 2766 CI ReadFile(2) = 6578 VI ReadFile(2) = 2922 Loadfile() = 2844 CI ReadFile(4) = 6265 VI ReadFile(4) = 2969 Loadfile() = 2875 CI ReadFile(8) = 6125 VI ReadFile(8) = 2953 Loadfile() = 2922 CI ReadFile(16) = 6078 VI ReadFile(16) = 3078 Loadfile() = 2907 CI ReadFile(32) = 6015 VI ReadFile(32) = 3016 Loadfile() = 2891 CI ReadFile(64) = 5984 VI ReadFile(64) = 3031 Loadfile() = 2906 CI ReadFile(128) = 6157 VI ReadFile(128) = 3109 Loadfile() = 2891 CI ReadFile(256) = 6093 VI ReadFile(256) = 3141 Loadfile() = 2938 CI ReadFile(512) = 4640 VI ReadFile(512) = 3094 Loadfile() = 2906 CI ReadFile(1024) = 3781 VI ReadFile(1024) = 3094 Loadfile() = 2891 CI ReadFile(2048) = 3453 VI ReadFile(2048) = 3141 Loadfile() = 2906 CI ReadFile(4096) = 3297 VI ReadFile(4096) = 3125 Loadfile() = 2968 CI ReadFile(8192) = 3172 VI ReadFile(8192) = 3110
Bryce
|
Top
|
|
|
|
Moderator: Jochen, Allen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Arend_, Mart
|
0 registered
and 323 anonymous users online.
|
|
|