Click here to Skip to main content
15,886,362 members
Please Sign up or sign in to vote.
1.00/5 (3 votes)
See more:
Can someone help speed this code up??
It currently uses string indexing..

How would you do it with pointers or shifts or logic or math??

I'm using FreeBASIC

n1 = "110110"

v1 = ( ( n1[ 0 ] - 48 ) * 2 ) + ( n1[ 1 ] - 48 )
v2 = ( ( n1[ 2 ] - 48 ) * 2 ) + ( n1[ 3 ] - 48 )
v3 = ( ( n1[ 4 ] - 48 ) * 2 ) + ( n1[ 5 ] - 48 )

What I have tried:

Just as it is string indexing..

Using v1 = val( "&B" + mid( n1 , 1 , 2 ) )
was my first attempt.. it was too slow..
It took 210 seconds for the program to run..

With the string indexing , it speed it up to 52 seconds , a lot faster..

Maybe some inline ASM ?? FreeBASIC allows inline ASM..

I'd like to get it even faster.. like 20 to 30 seconds or less.
Posted
Updated 11-Sep-21 14:28pm
v5

Without access to your whole code, we can't help you speed it up - a tiny fragment of code with no context to any looping or data access code doesn't let us know enough to even start optimising anything efficiently. Just three lines of code in isolation isn't going to take 50 seconds to run on an ZX Spectrum, let alone a modern PC - so the surrounding code is as likely to be the bottleneck!

Almost certainly, a competent ASM programmer could improve the speed - but an average or beginner ASM developer would probably be slower ... you'd need to look at the disassembly of the FreeBASIC EXE file to work out what the compiler was doing before even looking to see if it's worth tweaking.
 
Share this answer
 
Here's the main loop again..

I tweaked it a little.. using pointers..
Now it's down to under 25 seconds.. for a megabyte input..

It's using ubyte pointers... so it takes 6 operations to do 6 bits..

I couldn't figure out ushort ptr's..
It would only take 3 operations with ushort ptr's..

Can someone help me figure out ushort ptr's ????

BASIC
dim as string outs = ""
    dim as string n2
    dim as longint v1 , v2 , v3 , v4 , v5
    dim as ubyte ptr p = cptr( ubyte ptr , strptr( bits ) )
    for a as longint = 1 to len( bits ) step 6
        
        v1 = ( *p - 48 ) * 2 : p+= 1
        v1+= ( *p - 48 ) + 1 : p+= 1
        
        v2 = ( *p - 48 ) * 2 : p+= 1
        v2+= ( *p - 48 ) + 1 : p+= 1

        v3 = ( *p - 48 ) * 2 : p+= 1
        v3+= ( *p - 48 ) + 1 : p+= 1 
        
        v4 = ( v1 + v2 ) - 1
        v5 = ( v2 + v3 ) - 1
        
        if v2 mod 2 = 1 then v4+= 8
        if v2 mod 2 = 0 then v5+= 8
        
        n2 = "00"
        if v4 < 10 then n2[ 0 ] = 48 + v4 else n2[ 0 ] = 65 + ( v4 - 10 )
        if v5 < 10 then n2[ 1 ] = 48 + v5 else n2[ 1 ] = 65 + ( v5 - 10 )

        outs+= n2
            
    next
 
Share this answer
 
Here's the whole program...
It's in FreeBASIC

You need Zlib.dll the the directory with the compiled exe..

I got the Compress_loop() tweaked as much as i can...
The only thing left is inline ASM...

=======================================================
Maybe someone skilled in ASM can help speed it up????
=======================================================


For 1,000,000 bytes input..
It takes between 14 and 20 seconds to do 250 to 300 loops.
It loops until the compressed code , is bigger or equal to the input code..

BASIC
<pre>'=====================================================================
'=====================================================================
'Start Z lib
'=====================================================================
'=====================================================================
Namespace Zlibrary

#define Z_NO_COMPRESSION         0
#define Z_BEST_SPEED             1
#define Z_BEST_COMPRESSION       9
#define Z_DEFAULT_COMPRESSION  (-1)

#inclib "zlib"
Extern "C"
    Declare Function compressBound(Byval sourceLen As Ulong) As Ulong
    Declare Function uncompress(Byval dest As Ubyte Ptr, Byval destLen As Uinteger Ptr, Byval source As  Ubyte Ptr, Byval sourceLen As Ulong) As Long
    Declare Function compress(Byval dest As Ubyte Ptr, Byval destLen As Uinteger Ptr, Byval source As  Ubyte Ptr, Byval sourceLen As Ulong) As Long
    declare function compress2(byval dest as ubyte ptr, byval destLen as uinteger ptr, byval source as const ubyte ptr, byval sourceLen as uLong, byval level as long) as long
End Extern

Function getpassedinfo(text As String,Byref passed_length As Integer) As String
    Dim As String var1,var2
    Dim As Integer pst
    #macro splice(stri,char,var1,var2)
    pst=Instr(stri,char)
    var1="":var2=""
    If pst<>0 Then
        var1=Mid(stri,1,pst-1)
        var2=Mid(stri,pst+1)
    Else
        var1=stri
    End If
    #endmacro
    splice(text,"|",var1,var2)
    text=var2
    passed_length=Valint(var1)
    Return text
End Function

'=================   UNPACK ===============
Function unpack(file As String) As String
    Dim As Integer passed_length
    Dim As String text=getpassedinfo(file,passed_length)
    Dim As Integer stringlength,destinationlength
    stringlength=Len(text)
    destinationlength =passed_length
    Dim As Ubyte Ptr source
    Dim As Ubyte Ptr  destination =Callocate(destinationlength,1)
    source=@text[0]
    Var mistake=uncompress(destination,@destinationlength, source, stringlength)
    If mistake<>0 Then Print "There was an error":Sleep:End
    Dim As String uncompressed
    uncompressed=String(destinationlength,0)
    For i As Integer = 0 To destinationlength- 1
        uncompressed[i]=(destination[i])
    Next
    Deallocate destination
    Return uncompressed
End Function

'===================  PACK ============
Function pack(file As String) As String
    Dim As String text=file
    Dim As Integer stringlength,destinationlength
    stringlength=Len(text)
    destinationlength = compressBound(stringlength)
    Dim As Ubyte Ptr source
    Dim As Ubyte Ptr destination =Callocate(destinationlength,1)
    source=@text[0]
    Var mistake=compress2(destination, @destinationlength, source, stringlength , Z_BEST_COMPRESSION )''<----  use compress2
    If mistake <>0 Then Print "There was an error"
    Dim As String compressed
    compressed=String(destinationlength,0)
    For n As Integer=0 To destinationlength-1
        compressed[n]=destination[n]
    Next n
    compressed=stringlength &"|"+compressed
    Deallocate destination
    Return compressed
End Function

End Namespace
'=====================================================================
'=====================================================================
'End Z lib
'=====================================================================
'=====================================================================

'=====================================================================
'=====================================================================
'start program
'=====================================================================
'=====================================================================
Declare Function      compress_loop( chrs as string ) as string
Declare Function decompress_loop( chrs as string ) as string

'Set show to 1 for 8 byte printout , set show to 0 for compression printout
dim shared as longint show = 0

screen 19
dim as double time1 , time2 , time3 , time4
dim as longint loops = 0
do
   
    randomize
    
    dim as longint size
    if show = 1 then size = 8
    if show = 0 then size = 1000000
    
    dim as string s = ""
    s = space( size )
    dim as ubyte ptr ubp = cptr( ubyte ptr , strptr( s ) )
    For n As ulongint = 0 To size - 1
        *ubp = Int( Rnd * 256 ) : ubp+=1
    Next
   
    time1=timer
    'begin compress
        dim as string comp = s
        if show = 0 then
            loops = 0
            do
                loops+=1
                dim as longint chk = len(comp) - 10 '( size \ ( size * 100 ) ) 
                comp = compress_loop(comp)
                print
                print "c inp = " ; len( comp )
                comp = Zlibrary.pack( comp )
                print "c out = " ; len( comp )
                if len( comp ) >= chk then exit do
                if inkey = chr( 27 ) then end
            loop
        else
            for a as longint = 1 to 1 step 1
                comp = compress_loop(comp)
            next
        end if
    'end compress
    time2 = timer
   
    time3=timer
    'begin decompress
        dim as string final_out = comp
        for a as longint = 1 to 1 step 1
            final_out = decompress_loop(final_out)
        next
    'end decompress
    time4 = timer
   
   'sleep
   
    'print string(99,"=")
    'print "inp = " ; (s)
    'print string(99,"=")
    'print "out = " ; (final_out)
    print
    print "Loops = "  ; loops 
    print "input = "; size , "output = " ; len(comp) , "compression ratio  "; 100 - ( 100 / ( size / len(comp) ) ) ; "%"
    print
    print "compress time   = "; time2-time1
    print "decompress time = "; time4-time3
    print
    
    if s = final_out then print "Decompressed OK" else print "Decompression Failed."
    print string(99,"=")
   
    sleep
   
loop until inkey = chr(27)

sleep
end
'===============================================================================
'===============================================================================
'compress
'===============================================================================
'===============================================================================
Function compress_loop( chrs as string ) as string

    if show = 1 then
        print
        print "c inp = " ; len(chrs)  ' , chrs
    end if
    
    dim as ubyte count1 = 0
    dim as ubyte dec1
    dim as string str1
    do
        str1 = str( len( chrs ) / 8 )
        dec1 = instr( 1 , str1 , "." )
        if dec1 <> 0 then chrs+= chr( 0 ) : count1+= 1
    loop until dec1 = 0
    
    dim as string bits = ""
    dim as string zeros = string( 64 , "0" )
    dim as string n1
    dim as ulongint ptr ubp1 = cptr( ulongint ptr , strptr( chrs ) )
    for a as longint = 1 to len( chrs ) step 8
        n1 = zeros + bin( *ubp1 ) : ubp1+= 1
        n1 = right( n1 , 64 )
        bits+= n1
    next
    
    if show = 1 then print "c bin = " ; len( bits ) , bits

    dim as ubyte count2 = 0
    dim as ubyte dec2
    dim as string str2
    do
        str2 = str( len( bits ) / 6 )
        dec2 = instr( 1 , str2 , "." )
        if dec2 <> 0 then bits+= "0" : count2+= 1
    loop until dec2 = 0

    dim as string outs = ""
    dim as string * 1 n2 = " "
    dim as ubyte ptr n = cptr( ubyte ptr , strptr( n2 ) )
    dim as longint ptr p1 , p2 , p3 , p4 , p5
    dim as longint v1 , v2 , v3 , v4 , v5
    dim as ubyte ptr p = cptr( ubyte ptr , strptr( bits ) )
    for a as longint = 1 to len( bits ) step 6
        
        p1 = @v1
        *p1 = ( *p - 48 ) * 2 : p+= 1
        *p1+= ( *p- 48 ) + 1 : p+= 1
        
        p2 = @v2
        *p2 = ( *p - 48 ) * 2 : p+= 1
        *p2+= ( *p - 48 ) + 1 : p+= 1

        p3 = @v3
        *p3 = ( *p - 48 ) * 2 : p+= 1
        *p3+= ( *p - 48 ) + 1 : p+= 1

        p4 = @v4 : *p4 = ( v1 + v2 ) - 1
        p5 = @v5 : *p5 = ( v2 + v3 ) - 1
        
        if *p2 mod 2 = 1 then 
            *p4+= 8
        else
            *p5+= 8
        end if
        
        *n = ( *p4 shl 4 ) + *p5
        
        outs+= n2
            
    next
    
    if show = 1 then print "c out = " ; len( outs )  , outs
    
    dim as string final = chr( count1 ) + chr( count2 ) + outs
    
    if show = 1 then print "c fin = " ; len( final ) ' , final
    
    return final
   
end function
'===============================================================================
'============================================================================
Function decompress_loop( chrs as string ) as string

    print
    print "d inp = " ; len( chrs )
    
    return chrs

end function
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900