Jump to content
Sign in to follow this  
wisem2540

Array ppopulation is slow. Can someone help me speed it up please

Recommended Posts

wisem2540

I am doing 2 sets of WMI queries.  The first one simply querys for all drivers installed on the print server and trims it.  The second queries the printers themselves and includes several attributes.  On my print server, I have 445 objects. 

 

#include <Array.au3>
#include <Date.au3>

Global $x
Global $DriverList[0]
Global $PrinterInfo[0][6]
Global $File
Global $Date
Global $x =0
Global $pserver = "BJCPrint01"




$objWMIService = ObjGet("winmgmts:\\" & $pserver & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery ("SELECT * FROM Win32_PrinterDriver")


For $objItem In $colItems
   $String = StringTrimRight ($objitem.Name,StringLen ($objitem.Name) - StringInStr($objitem.Name,",")+1)
   _ArrayAdd ($Driverlist,$string)
Next
_ArrayDisplay ($Driverlist)

$objWMIService = ObjGet("winmgmts:\\" & $pserver & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery ("SELECT * FROM Win32_Printer")

For $objItem In $colItems

   _ArrayAdd ($PrinterInfo,$objitem.Name,0)

   $Port = $objItem.PortName
      If StringLeft ($Port, 3) = "IP_" Then
      $Port = StringTrimLeft ($Port, 3)
   EndIf
    $PrinterInfo[$x][1]=$Port

   $State = $objItem.PrinterState

   if $State = 0 Then $State = "Ready"
   if $State = 1024 Then $State = "Ready"; 1024 is "Printing"
   if $State = 16384 Then $State = "Ready"; 16284 is "Processing"
   if $State = 1 Then $State = "Paused"
   if $State = 129 Then $State = "Paused - Offline"
   if $State = 1027 Then $State = "Paused - Error"
   If $State = 131073 Then $State = "Paused - Toner/Ink Low"
   if $State = 128 Then $State = "Offline"
   if $State = 1154 Then $State = "Error - Offline"
   if $State = 8 Then $State = "Paper Jam"
   if $State = 1034 Then $State = "Error - Paper Jam"
   if $State = 131072 Then $State = "Toner/Ink Low"
   If $State = 262144 Then $State = "No Toner/Ink"
   if $State = 2 Then $State = "Error"
   if $State = 132 Then $State = "Deleting - Error"
   if $State = 1158 Then $State = "Error - Deleting - Offline"
   if $State = 1042 Then $State = "Error - Out of Paper"
   if $State = 16 Then $State = "Out of Paper"
   If $State = 4194304 Then $State = "Door Open"

      $PrinterInfo[$x][2]=$state
      $PrinterInfo[$x][3]=$objItem.Drivername
       $PrinterInfo[$x][4]=$objItem.Location
        $PrinterInfo[$x][5]=$objItem.comment
      ;_ArrayDisplay($Printerinfo)
      $x = $x + 1
   Next
    _ArrayDisplay($Printerinfo)

 

Share this post


Link to post
Share on other sites
iamtheky

Instead of * maybe only select Name from printerdriver, and then only 'Name,PortName,PrinterState,DriverName,Location,Comment' from Printer, returning 95% less stuff from WMI has to help a little bit.

 


,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
wisem2540

Thanks for your suggestion.  Some more info..   if I remove the arraydisplays, the script takes 56sec to complete.  At the top of my FOR loop, I added IF $X > 1 then Exit to see how long the WMI query itself was taking,  That was 1.2 sec.  All of the time seems to be spent in the FOR loop, populating the Array.

Share this post


Link to post
Share on other sites
wisem2540

Eventually, this will turn into a GUI application.  I will want to click on a PrinterName, and my idea was to perform an _Arraysearch to return the Index that the printer exists at, and then return the other properties.  Make sense?  Maybe there if a way for me to do this using the Object Collection and not use the array?  But as far as I know, Object Collections do not have indices correct? Such as $ObjItem[1], $ObjItem[2]

Edited by wisem2540

Share this post


Link to post
Share on other sites
iamtheky

could you declare $printerinfo with the number of elements in $colitems and then get rid of arrayadd and all the redims, idk if ubound would work?   That would win back some ms.

Edited by boththose

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
wisem2540

I declared $Printerinfo with 460 elements for testing, since i knew that would be big enough.  I dropped the _ArrayAdd in favor of $PrinterInfo[$x][0]=$objItem.Name.  Still 55sec

Share this post


Link to post
Share on other sites
iamtheky

how about making that $state stack of Ifs a bunch of elseifs or case statements? Checking each one of those Ifs each time, and not moving on after finding your match has to waste some time (though again, probably ms).

Edited by boththose

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
wisem2540

I dropped everything from the script except $PrinterInfo[$x][0]=$objItem.Name

 

If this case I am only populating 1 column of the array.  Still well above 50 sec.

Share this post


Link to post
Share on other sites
LarsJ

If you run this code, you'll figure out, that it's not the array that's slow.

Dim $PrinterInfo[460][10]
For $i = 0 To 459
    $PrinterInfo[$i][0]="Name"
Next

It's the objects and accessing the properties of the objects that's slow. Probably not much to do about it.

Share this post


Link to post
Share on other sites
wisem2540

I see.  I was under the impression that once the WMI query happened, that all of the data was already retrieved.  So you are saying that every time the For loop happens it is doing another query up to the print server?  Is there maybe another method I could or should be using to get this data?  I cannot have my app hanging for 1min every time someone tells it to query a different print server.

I could use _Netshare enum in the interest of speed I suppose.

Share this post


Link to post
Share on other sites
LarsJ

Share this post


Link to post
Share on other sites
wisem2540

Any recommendation on a new method?

Share this post


Link to post
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
Sign in to follow this  

×