Announcement

Collapse
No announcement yet.

copying characters from strings the fastest possible way without using asm

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

  • Paul Purvis
    replied
    BUCK
    THAT WAS AWESOME!
    thanks for the sharing your code, that really kicked some serious
    butt. an unbeliveable 3 times faster on my machine on your new code with
    the DIM ABSOLUTE of an array. pat yourself on the back for me, i thought
    the code i last wrote last would have been hard to improve over in speed and i am sure there
    may be a lot of people to benefit from it after seeing it.
    i figure i can now stop trying to improve the speed on this string routine.

    what was really amazing again was that i am home now and have a faster computer thank at work running windows
    2000 nt on a hp 1.1ghz althon machine and i ran those those routines in a window dos box and in a full screen
    mode, and surprising the windows box still ran the program faster, and believe this condition or not,
    the 500mhz intel computer at work, ran the routines so much faster than the machine at home which i would have
    thought would be twice as fast.

    i believe the video card or some other hardware different is the biggest difference.
    i booted my hp 1.1mhz machine in pure dos mode and ran the routines above and came to the
    the same speed in the routine as in a full screen mode in windows.
    i have a 550 amd pentium 1 chip also at my desk that out ran my faster machine
    at home.


    i will add a seperate note when i figure out, if ever i do figure out what
    is causing the problem, maybe it is just the video card.


    ------------------




    [This message has been edited by paul d purvis (edited October 11, 2003).]

    Leave a comment:


  • Buck Huffman
    replied
    Hi Paul

    Try this one.
    Code:
    ' starting after all metastatements
    DIM ABSOLUTE Video(3999) AS BYTE AT &H0B800
    DIM I AS INTEGER
    DIM CELL AS BYTE PTR
    DIM SCRNTEXTPTR AS BYTE PTR
    DIM SCRNTEXT AS STRING
    SCRNTEXT = SPACE$( 2000 )
    '
    INPUT "FIRST ROUTINE";A%
    B=TIMER
    FOR J=1 TO 10000
       CELL = &HB800 * 65536
       SCRNTEXTPTR = STRPTR32( SCRNTEXT )
       FOR I = 1 TO 4000
          @SCRNTEXTPTR = @CELL
          INCR SCRNTEXTPTR
          INCR CELL, 2
       NEXT
    NEXT
    PRINT TIMER-B
    '
    DIM ix AS INTEGER
    DIM pScreen AS BYTE PTR
    DIM pBuffer AS BYTE PTR
    DIM sBuffer AS STRING
    sBuffer = SPACE$(2000)
    '
    INPUT "SECOND ROUTINE";A%
    B=TIMER
    FOR J=1 TO 10000
       pBuffer = STRPTR32(sBuffer)
       FOR I = 0 TO 3999 STEP 2
          @pBuffer = Video(I)
          INCR pBuffer
       NEXT
    NEXT
    PRINT TIMER-B
    END
    '
    the second one was a bit faster on my machine

    Buck




    ------------------

    Leave a comment:


  • Paul Purvis
    replied
    thanks to all that answered
    and pondered on my message.

    what i really wanted was two things
    1 fast read the screen into a text variable without the screen attributes.
    2 fast string insertion

    after reviewing many notes of code in the book, a few on the forums, and
    notes from answers here is my code as of yet.
    it was really close to tom's

    what i meant by (fill,plug) was to insert characters from one string into another
    string. there is the MID$ statement, and i like it but it was slower than
    i wanted for a particular application.

    here is the code
    please feel free to edit the code and make it better anyone.
    i programmed the source on a pure dos system.
    i also ran the program on a windows nt 2000 system(500mhz), and was
    amased at how much faster the window text box mode is compared to the full screen mode.

    this program compares the speed of the my code to tom's, not that i
    am in competition with it. i wrote the program to test the best too
    codes i could find. it appears my code is faster and also note i made
    some miner changes to tom's code so that our code would be identical, basically
    removing the LEN statement and mutliplication in his code.


    REM $CPU 80386 ' program works on any CPU
    $OPTIMIZE SPEED ' make smallest possible executable
    $DEBUG MAP OFF ' turn off map file generation
    $DEBUG PBDEBUG OFF ' don't include pbdebug support in our executable
    $LIB COM OFF ' turn off PowerBASIC's communications library.
    $LIB CGA OFF ' turn off PowerBASIC's CGA graphics library.
    $LIB EGA OFF ' turn off PowerBASIC's EGA graphics library.
    $LIB LPT OFF ' turn off PowerBASIC's printer support library.
    $LIB IPRINT OFF ' turn off PowerBASIC's interpreted print library.
    $LIB FULLFLOAT OFF ' turn off PowerBASIC's floating point support.
    $ERROR BOUNDS OFF ' turn off bounds checking
    $ERROR NUMERIC OFF ' turn off numeric checking
    $ERROR OVERFLOW OFF ' turn off overflow checking
    $ERROR STACK OFF ' turn off stack checking
    $COM 0 ' set communications buffer to nothing
    $STRING 8 ' set largest string size at 8k
    $STACK 4096 ' let's use a 2k stack
    $SOUND 1 ' smallest music buffer possible
    $DYNAMIC ' all arrays will be dynamic by default
    $OPTION CNTLBREAK OFF ' don't allow Ctrl-Break to exit program
    $DIM NONE
    $COMPILE EXE ' this tells PB to make a standalone EXE
    $INCLUDE "PB35.INC"
    $LINK "PB35.Pbl"
    $EVENT OFF

    DIM I AS INTEGER
    DIM CELL AS BYTE PTR
    DIM SCRNTEXTPTR AS BYTE PTR
    DIM SCRNTEXT AS STRING
    SCRNTEXT = SPACE$( 2000 )

    INPUT "FIRST ROUTINE";A%
    B=TIMER
    FOR J=1 TO 10000
    CELL = &HB800 * 65536
    SCRNTEXTPTR = STRPTR32( SCRNTEXT )
    FOR I = 1 TO 2000
    @SCRNTEXTPTR = @CELL
    INCR SCRNTEXTPTR
    INCR CELL, 2
    NEXT
    NEXT
    PRINT TIMER-B

    DIM ix AS INTEGER
    DIM pScreen AS BYTE PTR
    DIM pBuffer AS BYTE PTR
    DIM sBuffer AS STRING
    sBuffer = SPACE$(2000)

    INPUT "SECOND ROUTINE";A%
    B=TIMER
    FOR J=1 TO 10000
    pBuffer = STRPTR32(sBuffer)
    pScreen = pbvScrnBuff
    FOR ix = 1 TO 4000
    @pBuffer = @pScreen
    INCR pBuffer
    INCR pScreen, 2 ' need to skip the display attribute, too
    NEXT
    NEXT
    PRINT TIMER-B
    END


    ------------------


    [This message has been edited by paul d purvis (edited October 10, 2003).]

    Leave a comment:


  • Tom Hanlin
    replied
    Compatibility... this code will be completely worthless for the Windows
    compilers. Actually, it doesn't translate to PB/Win at all, as the GUI
    design uses a completely different approach to display handling. Don's
    technique will translate well enough to PB/CC, although you would do better
    to INCR Tptr directly and throw away the P index. Saving
    the screen using the SCREEN function is going to be very slow under either
    DOS or Windows, though. Maybe page flipping would be a better approach?

    ------------------
    Tom Hanlin
    PowerBASIC Staff

    Leave a comment:


  • Tom Hanlin
    replied
    Hmmm, "copying(filling,plugging)" ... are these intended to be synonymous
    terms? I'm a bit confused as to what is wanted there.

    Screen copying, that's no problem. I gather we're dealing with an 80x25
    text-mode screen and just want to grab all the text. So:
    Code:
        DIM ix AS INTEGER
        DIM pScreen AS BYTE PTR
        DIM pBuffer AS BYTE PTR
        DIM sBuffer AS STRING
    
        sBuffer = SPACE$(80 * 25)
        pBuffer = STRPTR32(sBuffer)
    
        pScreen = pbvScrnBuff
    
        FOR ix = 1 TO LEN(sBuffer)
            @pBuffer = @pScreen
            INCR pBuffer
            INCR pScreen, 2   ' need to skip the display attribute, too
        NEXT
    ------------------
    Tom Hanlin
    PowerBASIC Staff

    Leave a comment:


  • Don Schullian
    replied
    It's been awhile since DOS days and as you DON'T want ASM then
    you might want to give this (untested) code a shot.

    Code:
    FUNCTION fReadScreen () AS STRING
     
      DIM Col  AS INTEGER
      DIM P    AS INTEGER
      DIM Row  AS INTEGER
      DIM Tlen AS INTEGER
      DIM Tptr AS BYTE PTR
      DIM Txt  AS STRING
     
      Tlen = (ScreenX * ScreenY) + ScreenY
      Txt  = STRING$(Tlen,32)
      Tptr = STRPTR(Txt)
     
      FOR Row = 1 to ScreenY
        FOR Col = 1 to ScreenX 
          @Tptr[P] = SCREEN(Row,Col)
          INCR P
        NEXT
        INCR P
      NEXT
     
      FUNCTION = Txt
     
    END FUNCTION
    ------------------
    C'ya
    Don
    [email protected]

    [This message has been edited by Don Schullian (edited October 09, 2003).]

    Leave a comment:


  • Paul Purvis
    replied
    thanks mel,

    that code is certainly standard and might be just the ticket for transferring
    code from one compiler to another from different companies.

    mel, please go back and reread my note, i made some modifications to my text
    in the first request for help.

    something i did not see before, is that maybe i should have used
    the INCR instruction rather that the J=J+1 to make a speed improvoement.


    but i am planning on staying with powerbasic and i need(or want)speed.
    i figure the best way to keep my older slower systems running is speed.
    the program above is my first tsr and i would like to keep the tsr for interferring
    with anything the computer might need as far as computer timing goes, so therfore
    i figure in a tsr, speed may be a key issue.

    i have not done any testing on that code but unless i am not mistaken
    it would be faster to leave a string(destination) located in memory where it is and fill the
    string with characters from the source string if the destination string was already initialized to a certain length
    and will not change in length of characters for the duration of the program.

    it might also help keep from fragmenting your memory by keeping the string at its location.
    i have had that problem in a different basic compiler before,
    when i only had 64k for code and 64k for data.

    ------------------




    [This message has been edited by paul d purvis (edited October 09, 2003).]

    Leave a comment:


  • Mel Bishop
    replied
    Originally posted by paul d purvis:
    SAVESCREEN$ = PEEK$(0,4000) ' save the entire screen
    J%=0
    FOR I%=0 TO 2000
    I%=I%+1
    J%=J%+1
    MID$(CHARACTERSONSCREEN$,J%,1)=MID$(SAVESCREEN$,I%,1)
    NEXT I%
    You are real close here. The save screen function consists of
    two bytes for each byte of screen saved. The first character is
    the background color attribute and the 2nd character is the
    actual character itself.

    The easiest way I have found to record the contents of a screen
    into a string array is:
    Code:
    a$ = ""
    for row% = 1 to 24    'or the number of rows you have on screen
    for col% = 1 to 80    'or the number of columns on screen
    
    y% = screen(row%,col%) 'Gives the ASCII value.
    a$ = a$ + chr$(y%)
    
    next col%
    'put Cr/Lf here if you want
    next row%
    May not be the most efficient but it works okay in TEXT mode.
    Graphics mode, on the other hand, is a horse of a different
    color.

    To copy text of one string varialbe to another:
    b$ = a$

    If you want to time a particular function:
    Code:
    mtimer
    for a = b to c
    ...process
    ...process
    next a
    t = mtimer
    print;t;
    If you want to stay with SAVESCREEN$, you will have to STEP 2
    in your For/Next loop
    Code:
    for x= 2 to len(savescreen$) step 2  'Start with the 2nd (1st text) character.
    t$ = t$ + mid$(savescreen$,x,1)
    next x
    ------------------




    [This message has been edited by Mel Bishop (edited October 09, 2003).]

    Leave a comment:


  • copying characters from strings the fastest possible way without using asm

    hello everybody,


    i am a newcomer to powerbasic even though i purchased it some time ago
    and had it laying on the shelf, like i have the 2 powerbasic for windows compilers
    on the shelf right now, but i know they will come in use later.
    i wanted to support powerbasic in its ongoing ventures so my programs will be ongoing.

    i do not understand much asm or want to use asm code if at all possible to keep
    my programs in a stardard code so i can upgrade from powerbasic for dos
    to powerbasic for windows later.
    i perfer to use compiler builtin functions when possible for compatiblity reasons.


    i have read about cell pointers and strptr and all the other powerbasic
    functions concerning pointers to strings and still a bit confused on how to accomplish
    what i want to write.

    in the powerbasic for dos 3.5 users guide on the section of pointers(@)(page 91), i have read about using the
    pointers to read the screen fast but also i want to copy(fill,plug) a string from one string to another.


    i do not want to write a function(routine) that is called , i want an inline code, but beggers
    cannot be chosers.

    i just want to copy(fill,plug) characters for one string to another as fast a possible in a program
    that i have watching what is displayed on the screen and taking some action if certain information
    is displayed on the screen, the program is a tsr that is loaded before a certain program
    and unloaded after the program has finished. it will activate every 1 second if there is
    no activity by popping down using the POPUP QUIET 18 command for tsr's.

    here is what i have so far and it is abbreiated for general purposes


    'i initialize this variable in the beginning of my progam
    'i never want the variable to be less or more than 2000 characters
    CHARACTERSONSCREEN$=SPACE$(2000)


    'here is the kicker
    'i want to transfer the characters from the screen to the above
    'string variable as fast as possible without using any asm code.
    'and here is how i do that
    'i do this many times in the tsr
    'i do not know but i have read that reading the screen with pointers
    'is a faster way to go in copying(filling,plugging) of data in powerbasic

    DIM J AS INTERGER
    DIM I AS INTERGER
    ' this next line is only placed once in the program
    CHARACTERSONSCREEN$=SPACE$(2000)

    SAVESCREEN$ = PEEK$(0,4000) ' save the entire screen
    J=0
    FOR I=0 TO 2000
    I=I+1
    J=J+1
    MID$(CHARACTERSONSCREEN$,J,1)=MID$(SAVESCREEN$,I,1)
    NEXT I

    also i want to mention, i would also like to transfer(copy,fill,plug) characters
    from one string to another fast without using asm code.
    the characters from the string being copied may only be a few characters in
    length to the total characters in the string and being placed in the
    middle of the second string.

    maybe somebody out there has already gone through some of this kind of testing for speed
    and has some answers for me.

    thanks in advance.


    ps.
    a big thanks to all those who understand asm and help me and others with by suppling your code for
    things that might otherswise be unpossible to write in normal(text)source code and for powerbasic having
    the ability to easily add asm code into the source code. both are applauded by myself.


    ------------------




    [This message has been edited by paul d purvis (edited October 09, 2003).]
Working...
X