Announcement

Collapse
No announcement yet.

Shell "prog.bat"

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Shell "prog.bat"

    I have cut & pasted a small piece of code from one app to another.
    Code in 1st app takes 1.2 secs but 9.5 secs in 2nd app.
    1st app is 46K and 2nd app is 62K and are similar.
    Both apps run in Windows 98SE.
    The code copied simply wites a small batch file, shells it then kills it.
    I've checked memory indicators and all seems OK.

    There's not much to go on here but I cannot figure what other info
    is relevant.

    I'm hoping someone has seen this event in their own work and
    fathomed out what was going on.

    ------------------
    David Roberts

  • #2
    The point of the batch file was to get errorlevels from scanreg
    so I implemented, via a pbu, Exec by Keith Foster from Lance Edmonds' post
    March 5 2001 "return values from shelled programs"

    The exe increased from 63559 to 63780 which is neither here nor
    there but it still took 9.4 seconds.

    I would have thought Exec would leave the batch file method standing
    since the latter writes the bat, shells out creating a txt with the
    errorlevel, txt is read and then both the bat and txt are killed.
    A sledgehammer to crack a nut but no worries about SETMEM!

    Not killing the bat and running from the desktop comes back in about
    1 second in line with the 1st app where the orig code was pasted from.

    Something is wrong here - Exec should have stormed home.


    ------------------
    David Roberts

    Comment


    • #3
      I've run scanreg in DOS and it took 3 seconds to scan the reg.
      A Exec version took 10.4 seconds to do the same and bring back
      an error level.
      I hadn't realised how slow PowerBasic is!
      I'm now wondering how on earth the 1st app is managing to come
      back as fast as the batch file!

      ------------------
      David Roberts

      Comment


      • #4
        The bottle neck is not very likely to be PowerBASIC as you suggest, but as you have not provided the actual code for anyone else to try, and we don't know if you are testing both apps from the same command-line or if you are using different DOS windows, or whether you have other apps running that are stealing CPU time in big quantites, or...something else again.

        At this point, the best we can do is guess what is going on. First, how many PC's have you made the comparison on?

        Also, the Windows multi-tasking settings could easly explain the problem. Specifically, the "idle sensitivity" setting could be much lower on the "faster" app. Do you know how to adjust the Properties of a DOS window.

        Next, how does the execution speed compare when you run it in plain MSDOS mode (ie, boot to the command-line, not to Windows)?

        The first step to investigating the problem would be to write a very simply app that simply runs the .BAT file, and reports the time taken to perform the task. This will hopefully eliminate the other code in your app as a possible cause of the problem.

        For example, you might write something simple, like this:
        Code:
        $COMPILE EXE
        $ERROR ALL OFF
        t! = TIMER
        SHELL "x.bat"
        PRINT TIMER - t!
        To test this code, you'll need to execute the EXE from a DOS command-line, and stick to using the same DOS command interpreter and DOS window to run all the tests to eliminate shortcut/PIF file configuration as a cause of the problem.

        If this code runs fast, then chances are the problem is something else in your real program, or it could be that your test .BAT file is having a much greater impact on system speed than you might have imagined.

        OTOH, if the speed is low, then you might check that the command-interpreter is working ok, and that there is plenty of free space on the drive, and the root folder is not full.


        ------------------
        Lance
        PowerBASIC Support
        mailto:[email protected][email protected]</A>
        Lance
        mailto:[email protected]

        Comment


        • #5
          Hello Lance

          I have a scientific/statistics background so when comparing fighters I make sure they are in the same ring and at the same time.
          Of course, there may be one or two variables that are different between the camps and they are being looked for.

          Your code snippet is almost identical to the one I have been using.

          In DOS, I'm getting 3 v 10 secs as opposed to 2 V 9 secs [roughly].

          I'm in the process of stripping the code down to the bare minimum and I'll post the result of that.
          Of course, if the loss of speed goes then I'll have stripped something off which is causing the problem.

          I'll be back.

          Cheers.

          ------------------
          David Roberts

          Comment


          • #6
            Yeah, the loss of speed went whilst I was stripping the code down.

            The errorlevels are considered in a select construct. Case 0 is large(ish) & the most likely scenario so I put an END before it and ripped it out.

            I got my <2 secs back. Put Case 0 into a Gosub and back to 9 seconds.

            So, it's got nothing to do with the bat file.

            I'll leave Case 0 alone and strip elsewhere. If I cannot get back to <2 secs I'll consider Case 0.


            ------------------
            David Roberts

            Comment


            • #7
              I've ripped other code out and got <2 seconds so it's not Case 0 - it's the exe size.

              It's currently sitting at 63850 bytes.

              I've never concerned myself with size. I have one app at 87223 and there have never been any problems with that.
              So, I duplicated a few routines to make the 62K app larger but that didn't help.
              I've thrown in a $segment here and there but no help.

              I'll shuffle the code around and see what happens.

              Seems odd. The program works - it's just that at it's current size shelling out takes 9 secs instead of 2.


              ------------------
              David Roberts

              Comment


              • #8
                Over the years I've written hundreds of apps with PB/DOS that range from a few KB to 250-300Kb and I've never experienced a problem with a "slow" SHELL, so I'm still suspicious that something else in your app is having a big effect.

                While your EXE size might be quiet small, the memory image size of the app and the amount of free memory are much more important aspects. Have you compared the results of FRE(-1) and FRE(0) between your two apps before the SHELL statement?

                Also, to help eliminate low-memory problems, you might try referencing the FRE(0) function and issue a MEMPACK before the SHELL, just to maximize available memory. (completely compressing fragmented memory can be a bit more complex than this, but its worth at least an initial investigation in your apps).

                As an aside, low conventional memory can be a major concern when SHELLing to external apps, so I routinely make use of UltraShell from www.informs.com - I highly recommend it to solve any free memory-related problems. US works buy swapping out almost the entire conventional memory area to EMS or to a temporary disk file, leaving around 5Kb in use. This ensures that the SHELLed app will be able to use almost the entire conventional memory area for it's operations.

                Good luck!

                ------------------
                Lance
                PowerBASIC Support
                mailto:[email protected][email protected]</A>
                Lance
                mailto:[email protected]

                Comment


                • #9
                  Quite a few months ago I had a problem with a large registry and had a massive clean out of rarely used apps and I also examined the conventional memory status and found room for reduced usage.

                  I always use MEMPACK before shelling out.

                  This is what I have just before shelling out.
                  46K app fre(0) 32750 fre(-1) 516832
                  62K app fre(0) 32750 fre(-1) 501792

                  So, I am awash with conventional memory.
                  scanreg, the app I'm shelling, can use an enormous amount of memory in a DOS context I doubt I am pushing the limit with my current registry.

                  The odd thing is an app using Exec with only a handful of lines is also taking in excess of 9 secs to complete.
                  Using Exec on other progs which generate errorlevels is coming back to me in millisecs.

                  I'll try and get access to another PC.


                  ------------------
                  David Roberts

                  Comment


                  • #10
                    Just a quick word.

                    Exec threw a wobbly on an unrelated exercise. DOS needed more parameters. I tried another routine which which needed several but also was happy with none. In each case it Exec behaved as if given none.

                    So, I wrote another pbu using your 2nd suggestion from your post cited above.

                    For the record this is how it was entered in my machine.

                    $CPU 80386
                    $LIB ALL OFF
                    $ERROR ALL OFF
                    $OPTIMIZE SPEED
                    $COMPILE UNIT

                    FUNCTION EXEC( BYVAL program AS STRING, BYVAL par AS STRING ) PUBLIC AS INTEGER
                    DIM block AS STRING * 14
                    DIM parm AS STRING * 50
                    DIM zbuffer AS STRING, dummy AS LONG
                    zbuffer = program + CHR$( 0 )
                    LSET parm = CHR$( LEN( par )) + par + CHR$( 13 )
                    LSET block = CHR$( 0 ) + CHR$( 0 ) + MKI$( VARPTR( parm )) + MKI$( VARSEG( parm ))
                    dummy = SETMEM( -500000 )
                    REG 1, &H4B00
                    REG 9, VARSEG( block )
                    REG 4, STRPTR( zbuffer )
                    REG 8, STRSEG( zbuffer )
                    REG 2, VARPTR( block )
                    CALL INTERRUPT &H21
                    IF REG( 0 ) AND 1 THEN
                    exec = 255
                    SELECT CASE REG( 1 )
                    CASE 1, 2, 3, 5, 8, 10, 11
                    dummy = SETMEM( 500000 )
                    EXIT FUNCTION
                    END SELECT
                    END IF
                    REG 1, &H4D00
                    CALL INTERRUPT &H21
                    exec = REG( 1 )
                    dummy = SETMEM( 500000 )
                    END FUNCTION

                    and I tested it using the following:

                    $INCLUDE "PB35.INC"
                    DIM ErrorL AS INTEGER, t as single, mem as integer
                    t=timer
                    mem=fre(-1)\1024
                    ErrorL=Exec("c:\windows\command\scanreg.exe","/nop /win")
                    print timer-t;mem
                    if ErrorL=254 then print "Not enough memory"
                    if ErrorL=253 then print "File not found"

                    I kept reducing the conventional memory allocation via the Total entry on the Memory tab of the Properties sheet.

                    I got 'Not enough memory' with mem @ 241K and the app worked with mem @ 281K.
                    On Auto mem was @ 525K. With a 40K step we cannot get an exact figure but there seems to be at least 244K not used by scanreg.

                    The app above takes over 9 secs on my machine; about the same as the 62K app (which does a lot more besides)using the bat file method.

                    This questions the 46K app using the bat file method.

                    I renamed User.dat from the desktop, after taking a valium[!], and all three apps agreed that one of the reg files was missing so the 46K app is working proerly.

                    You may not recognise the scanreg switches - it would take too long, here anyway, to explain what I am up to.

                    Cheers.

                    ------------------
                    David Roberts

                    Comment


                    • #11
                      Oh, I changed PBEXEC to EXEC to save time changing the library builder and so on.

                      ------------------
                      David Roberts

                      Comment


                      • #12
                        What I hadn't tried was the new version of Exec in DOS.
                        Down to 3 secs so the first version of Exec is suspect somewhere.
                        The scanreg switch /win is dropped when in DOS.

                        It's getting a bit heavy for me to figure out why the new version of Exec doesn't like working within a Windows session.

                        All I need to do now is fathom out why that 46K bat method is so fast in Windows.


                        ------------------
                        David Roberts

                        Comment


                        • #13
                          I've got the 62K app coming back in 3.5 secs

                          by shell "start /w prog.bat" ----- (1)

                          If I use start /w scanreg... in the bat file I lose the gain.

                          Reverse the start /w and no effect.

                          So, Exec in DOS and bat file method in Windows with (1).

                          Strewth!

                          I get two instances of command.com in Windows but what the heck.

                          Doing the same with the 46K app comes back in 1 sec but occasionally will slow to 3 secs. It is consistent without implementing start /w.I suppose this is another example of DOS not being happy at sharing a bed with Windows.





                          ------------------
                          David Roberts

                          Comment


                          • #14
                            Oh dear. I have not been able to repeat the new Exec success in DOS.

                            Using the above pbu I ran this in DOS:
                            -----------------
                            $INCLUDE "PB35.INC"
                            DIM ErrorL AS INTEGER, t AS SINGLE, save1t AS SINGLE, save2t AS SINGLE

                            t=TIMER
                            ErrorL=Exec("c:\windows\command\scanreg.exe"," /nop")
                            save1t=TIMER-t

                            t=TIMER
                            shell "scanreg.exe /nop"
                            save2t=TIMER-t
                            print save1t;save2t
                            -----------------

                            and got 10.93 3.74 with pretty much the same running another 6 times.

                            With an Athlon 600Mhz I've got an Atari ST next door laughing at that 11 secs!


                            ------------------
                            David Roberts

                            Comment


                            • #15
                              For the sake of completeness here's the sledgehammer code:

                              $INCLUDE "PB35.INC"

                              DIM ErrorL AS INTEGER, t AS SINGLE

                              OPEN "Scan.bat" FOR output AS #1
                              PRINT #1, "@echo off"
                              PRINT #1, "scanreg /nop"
                              PRINT #1, "for %%e in (0 2 249 250 251 252 253 254) do if errorlevel %%e set errorl=%%e"
                              PRINT #1, "> error.txt echo %errorl%"
                              CLOSE #1

                              IF NOT exist( "scan.bat" ) THEN
                              PRINT " Scan.bat not found. Program terminated"
                              END
                              ELSE
                              t = TIMER
                              SHELL "scan.bat"
                              PRINT TIMER - t
                              KILL "scan.bat"
                              END IF

                              IF NOT exist( "error.txt" ) THEN
                              PRINT " Error.txt not found. Program terminated"
                              END
                              ELSE
                              OPEN "error.txt" FOR INPUT AS #1
                              INPUT #1, ErrorL
                              CLOSE #1
                              KILL "error.txt"
                              END IF
                              PRINT ErrorL

                              This is the original stuff that worked for the 46K app but not the 62K app.

                              In DOS the above came back in 3.9 secs. The cost in getting the errorlevel is negligible and surprising given all the disk access.

                              I've noticed your having a go at members for not supplying code.
                              My last few posts will cost you a few coffees!

                              Cheers

                              ------------------
                              David Roberts

                              Comment


                              • #16
                                Hi David,

                                I'm a bit confused by your last sequence of posts - what are the two different versions of EXEC() that your refer?

                                However, rather than going around in circles, can you please ZIP and email the various forms of the code and I'll run them on my Win98 box and see if I can get similar results or spot anything problematic.

                                Thanks!

                                ------------------
                                Lance
                                PowerBASIC Support
                                mailto:[email protected][email protected]</A>
                                Lance
                                mailto:[email protected]

                                Comment


                                • #17
                                  Hi Lance

                                  Ref Topic: 'return values from shelled programs'
                                  Exec V1: Your post March 05 ,2001 04:22AM
                                  Exec V2: -do- 04:24AM

                                  The 2nd version was actually called PBExec but, for convenience, I used the same name.

                                  The 1st version didn't work for me. It seemed that the parameter string was being read as empty. Exec V2, PBExec, worked OK.

                                  I'll knock out a ZIP file and email it as requested.

                                  ------------------
                                  David Roberts

                                  Comment


                                  • #18
                                    Update: David advised that SCANREG requires very close to 600Kb of conventional memory or it slows down substantially. The differences discussed earlier in this topic are caused by the slightly differing amounts of free conventional memory available when the SHELL/EXEC starts SCANREG.


                                    ------------------
                                    Lance
                                    PowerBASIC Support
                                    mailto:[email protected][email protected]</A>
                                    Lance
                                    mailto:[email protected]

                                    Comment


                                    • #19
                                      Just a final note.

                                      That 600Kb includes the additional conventional memory used by Windows and the DOS app. Running scanreg from the DOS prompt would find a lot more memory.

                                      Got a copy of UltraShell. The additional memory got by paging the app to XMS resulted in the app scanning at 1.2 seconds which is one heck off a lot better than 9!!!

                                      ------------------
                                      David Roberts

                                      Comment

                                      Working...
                                      X