Speed Vs Readability-VBForums
Page 1 of 2 12 LastLast
Results 1 to 40 of 51

Thread: Speed Vs Readability

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Feb 2017
    Posts
    120

    Speed Vs Readability

    This question generated from comment made by DataMiser
    regarding speed on the construction used in my thread: "Multiple Assignment Same Line - How To Interpret?" http://www.vbforums.com/showthread.p...terprethttp://

    I was taught to program using one way in one way out:

    Code:
    Private Function OneWayInOut(a As integer, b as Integer) As Boolean
    
        Dim blnReturn As Boolean
    
        blnReturn = False   '<<I recognize variable defaults to False
    
        If a = b Then
           blnReturn = True
        End If
    
        OneWayInOut = blnReturn
    
    End Function
    I've always used the above construct unless I have a long procedure where it needs to be short circuited:

    Code:
    Private Function ShortCircuit (a As integer, b as Integer) As Boolean
    
        ShortCircuit = False
    
        If a = b Then
           ShortCircuit = True
           Exit Function
        End If
    
    End Function
    I've always wanted to look at the ASM for VBClassic to see how any procedure is converted to ASM for the compiler, but unknown how to get ASM for VB Classic.

    So my questions are:
    1) Other than doing a timing test on a procedure with say 100,000 iterations, how is one determining which construct is faster?
    2) Anyway to get the ASM for a VB Classic procedure?
    Last edited by vb6forever; Sep 7th, 2017 at 09:47 AM.

  2. #2
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,605

    Re: Speed Vs Readability

    Compile it and disassemble it? I use OlyDbg per Trick's recommendation.
    I suspect the compiler will treat the two the same, but I would have to check.
    Imagine what it would be like to set breakpoints in, or step through subclassing code;
    and then being able to hit stop/end/debug or continue, without crashing the IDE.

    VB6.tlb | Bulletproof Subclassing in the IDE (no thunks/assembly/DEP issues)

  3. #3
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    31,285

    Re: Speed Vs Readability

    I was taught and stand by the Single Entry, Single Exit methodology too... it's served me well over the years.

    In the example you've given, odds are, the difference in the ASM is minimal... the instruction set is going to be virtually identical... so in that case, you're running millions before you see any performance differences.

    Typically I think the way that most people determine what the optimal performance method is, is to wrap the methods in a couple of timers (not Timers but some kind of stopwatch time functionalioty) and run them on massive order of times, run those several times, to get an average, and then do a comparison.

    That said, unless time truly is critical, with the speed of machines these days, the difference in the things like above, are largely negligible, and so come down to style and shop standards.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  4. #4

    Thread Starter
    Lively Member
    Join Date
    Feb 2017
    Posts
    120

    Re: Speed Vs Readability

    Dexwerx:
    Must missed Tricks post on OlyDbg. Will Try and Find it. Thanks

    techgnome:
    odds are, the difference in the ASM is minimal
    My guess to, but curious to know if / how the compiler is optomizing.

  5. #5
    PowerPoster
    Join Date
    Oct 2013
    Posts
    2,917

    Re: Speed Vs Readability

    Just as a comment:
    Code:
    Private Function ShortCircuit (a As integer, b as Integer) As Boolean
        ShortCircuit = (a = b)
    End Function

  6. #6
    PowerPoster
    Join Date
    Feb 2012
    Location
    West Virginia
    Posts
    12,182

    Re: Speed Vs Readability

    I also believe in the single entry single exit concept though I will make exceptions sometimes.

    I really hate to see code like this
    Code:
    If Something then 
        Exit Sub
    End IF
    'do some stuff
    It makes more sense to me to write it as
    Code:
    If Not Something Then
        'do some stuff
    End If
    Hard for me to say based on the samples here as the function is so simple that it does not need to exist and would be faster to not have it

    So instead of calling a function [which btw is a bit slower than inline code
    Code:
    x=ShortCircuit(a,b)
    This would be faster and shorter though maybe harder to read
    Code:
    x=(a=b)
    Another option would be
    Code:
    X=Not(a<>b)
    And of course
    Code:
    If A=B then x=True Else X=False

  7. #7
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,605

    Re: Speed Vs Readability

    I prefer early exit, simply from my assembly days, but as tg said - unless it's actually a time critical piece of code it's pretty arbitrary.
    Even if it was time critical, you still wouldn't see much of a difference.

    What you don't want to do is write something like this piece of .NET code

    Code:
     Public Shared Function ReverseHex(ByVal imei As String) As String
            Dim str2 As String = imei
            If String.IsNullOrEmpty(str2) Then
                Return String.Empty
            End If
            Dim builder As New StringBuilder
            Dim num2 As Integer = (str2.Length - 2)
            Dim i As Integer = 1
            Do While (i <= num2)
                builder.Append(New String(Enumerable.ToArray(Of Char)(Enumerable.Reverse(Of Char)(str2.Substring(i, 2)))))
                i = (i + 2)
            Loop
            Return builder.ToString
           
        End Function
    Last edited by DEXWERX; Sep 7th, 2017 at 11:48 AM.
    Imagine what it would be like to set breakpoints in, or step through subclassing code;
    and then being able to hit stop/end/debug or continue, without crashing the IDE.

    VB6.tlb | Bulletproof Subclassing in the IDE (no thunks/assembly/DEP issues)

  8. #8
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    3,287

    Re: Speed Vs Readability

    Oh wow, I've got different opinions about this too. Maybe I'm the odd man out, but I don't like huge indentions when they're just not necessary. In other words, if there are two or three validity checks to be performed before I actually do something in a procedure, I'll perform those validity checks, and get out quickly if they fail.

    Also, if I'm just looking for one occurrence in some list, once I find it, I'll exit the procedure. I just see no reason to execute an "Exit Do" or an "Exit For", just to make sure I exit at the bottom.

    Also, what if you're using error trapping? You can't just let your procedure fall into the error trapping routine each time. In that case, you've got to have an Exit [procedure].

    Here's an example with a bit of validation:

    Code:
    
    
    Public Sub SelectAllListItems(lst As ListBox)
        ' Does nothing if multiselect is false.
        Dim i As Integer
        If lst.MultiSelect = 0 Then Exit Sub
        '
        For i = 0 To lst.ListCount - 1
            lst.Selected(i) = True
        Next i
    End Sub
    
    
    Here's an example that exits when we find what we're after:

    Code:
    
    Public Function SelectedOptIndex(opt As Object) As Variant
        ' Returns the index number of a selected option button
        ' in an option button array.  Returns NULL if none selected.
        Dim o As OptionButton
        '
        For Each o In opt
            If o.Value Then
                SelectedOptIndex = o.Index
                Exit Function
            End If
        Next o
        SelectedOptIndex = Null
    End Function
    
    Here's an example that exits to avoid falling into error trapping:

    Code:
    
    Public Function IsInCollection(coll As Collection, Key As String) As Boolean
        On Error GoTo NotInCollection
        IsObject coll.Item(Key)
        IsInCollection = True
        Exit Function
        '
    NotInCollection:
    End Function
    
    
    Also, regarding initializing values to zero (or vbNullString), I tend to not do that unless it's a long procedure that uses the same value over and over. For instance, I might have some iPtr variable that is used in six different loops in the same procedure. After the first loop, I must be sure to reset it to zero, or it may have some bogus value. In this particular case, I will set it to zero before the first loop, just for consistency. However, if it's a simple procedure something like the above examples, I've learned to trust that VB6 will initialize variables correctly. It will also initialize function returns correctly, such as what happens in my last example (above) if there's an error.

    And, this is all just my humble opinion. I suppose we all have our own styles. So long as things are correctly indented, and we forget that we have the GoTo statement, I think we should respect that there are different styles.

    Best Regards,
    Elroy

    EDIT1: Actually, my error trapping example isn't that great, as nothing is done in the error trapping. However, I think people will understand my intent.

    EDIT2: Here's a better example about not falling into error trapping:

    Code:
    
    Public Function SafeFileCopyEx(sSourcePath As String, sDestinationPath As String, Optional bQuietErrors As Boolean = False) As Long
        ' Returns one of the following.
        ' 0 = all okay.
        ' 1 = error but continue.
        ' 2 = error and cancel copying.
        ' 3 = quiet error.
        Dim sMsg As String
        Dim rtn As Long
        On Error GoTo FileCopyError
        FileCopy sSourcePath, sDestinationPath
        Exit Function
    FileCopyError:
        If bQuietErrors Then
            SafeFileCopyEx = 3
        Else
            sMsg = "Source file: " & sSourcePath & vbCrLf
            sMsg = sMsg & "The error '" & Error(Err) & "' occurred while copying this file."
            rtn = MsgBox(sMsg & "  The program will continue but this file will not be backed up.", vbSystemModal + vbCritical + vbOKCancel, "Folder Backup: Error")
            If rtn = vbCancel Then
                SafeFileCopyEx = 2
            Else
                SafeFileCopyEx = 1
            End If
        End If
    End Function
    
    
    Last edited by Elroy; Sep 7th, 2017 at 11:55 AM.
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  9. #9
    Fanatic Member PlausiblyDamp's Avatar
    Join Date
    Dec 2016
    Location
    Newport, UK
    Posts
    605

    Re: Speed Vs Readability

    Quote Originally Posted by Elroy View Post
    Oh wow, I've got different opinions about this too. Maybe I'm the odd man out, but I don't like huge indentions when they're just not necessary. In other words, if there are two or three validity checks to be performed before I actually do something in a procedure, I'll perform those validity checks, and get out quickly if they fail.

    Also, if I'm just looking for one occurrence in some list, once I find it, I'll exit the procedure. I just see no reason to execute an "Exit Do" or an "Exit For", just to make sure I exit at the bottom.
    I'm with you on this one. I much prefer functions that do their validation up front and bail out early,with an appropriate return value or exception, rather than 90% of the function code being nested inside and if statement.

    Far too often I find the single exit approach involves extra variables being used to track the result that will eventually be returned rather than just returning the value straight away. I just find tracking these extra variables and dealing with the nesting just mental clutter that doesn't really help me understand what the code is doing.

    To answer the big question "Speed Vs Readability" I would always go for readability unless the code was very performance critical and the readable version performed noticeably slower in production.

  10. #10
    Fanatic Member
    Join Date
    Feb 2015
    Posts
    863

    Re: Speed Vs Readability

    In order to see an assembly code of a function you can use OllyDbg and use debug symbols.
    For example, we have a module with your functions:
    Code:
    Option Explicit
    
    Public Sub Main()
        OneWayInOut 1, 2
        ShortCircuit 1, 2
    End Sub
    
    Private Function OneWayInOut(a As Integer, b As Integer) As Boolean
    
        Dim blnReturn As Boolean
    
        blnReturn = False   '<<I recognize variable defaults to False
    
        If a = b Then
           blnReturn = True
        End If
    
        OneWayInOut = blnReturn
    
    End Function
    
    Private Function ShortCircuit(a As Integer, b As Integer) As Boolean
    
        ShortCircuit = False
    
        If a = b Then
           ShortCircuit = True
           Exit Function
        End If
    
    End Function
    For speed you use all optimization options:

    Save project and compile an EXE file. Then you should open the EXE file in OllyDbg and select View->Source Files and select your desired module:

    Double click on the line with 'arrow' move you to disassembly code:

    As you can see smart vb6 compiler/linker merge two functions to single.

    You can use also my Inline Assember Add-in and then you can use assembly code directly in VB6.

    ADDED:

    For acceleration you can use ByVal statement as well.

  11. #11
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    3,287

    Re: Speed Vs Readability

    I actually go back-and-forth on this "Speed Vs Readability" issue. For instance, we had a recent thread where I was explaining multiple equal (=) signs on a single line, and gave this code as an example:

    Code:
    
    Public Function bFromYN(s As String) As Boolean
        ' Y or y returns true.  All else returns false.
        bFromYN = UCase$(s) = "Y"
    End Function
    
    However, people not familiar with using the equal sign as a boolean test may not find that code very readable, and might prefer the following:

    Code:
    
    Public Function bFromYN(s As String) As Boolean
        ' Y or y returns true.  All else returns false.
        If UCase$(s) = "Y" Then
            bFromYN = True
        Else
            bFromYN = False
        End If
    End Function
    
    But this is just a matter of not understanding all the nuances of the language. IMHO, the first conceptualization is absolutely fine.

    In fact, to push this a bit farther, I'd also find the following conceptualization to be perfectly acceptable, understanding that VB6 is going to initialize the return to be False, unless explicitly changed.

    Code:
    
    Public Function bFromYN(s As String) As Boolean
        ' Y or y returns true.  All else returns false.
        If UCase$(s) = "Y" Then bFromYN = True
    End Function
    
    In other words, if we're making things more clear for people who don't understand all the nuances of the language, then that's not necessarily a good thing.

    However, there are also cases where code is just written in a way that it appears tied into knots (even if it works). That's also obviously a bad thing.

    For me personally, I tend to believe that well organized code runs faster than unorganized code in a great many cases. However, I also believe in "getting work done" rather than worrying about a couple of clock cycles, is also a good thing. (Some C programmers are absolutely obsessed with spending days to make sure they have the absolute fastest realization of some code concept. And, IMHO, when trying to get work done, this is sometimes just a waste of time.)

    Best Regards,
    Elroy
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  12. #12
    Fanatic Member PlausiblyDamp's Avatar
    Join Date
    Dec 2016
    Location
    Newport, UK
    Posts
    605

    Re: Speed Vs Readability

    Now oddly enough I find the sample
    Code:
    Public Function bFromYN(s As String) As Boolean
        ' Y or y returns true.  All else returns false.
        If UCase$(s) = "Y" Then bFromYN = True
    End Function
    more readable than either of the other two snippets you posted, I am not sure what it is but I just don't like the syntax of
    Code:
     bFromYN = UCase$(s) = "Y"

  13. #13
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,605

    Re: Speed Vs Readability

    Haha, not only did the compiler optimize them to be the same, but then it removed one.

    @TheTrick - why can I not see the View-->Source Files ?

    I definitely have the pdb file generated.
    Imagine what it would be like to set breakpoints in, or step through subclassing code;
    and then being able to hit stop/end/debug or continue, without crashing the IDE.

    VB6.tlb | Bulletproof Subclassing in the IDE (no thunks/assembly/DEP issues)

  14. #14

  15. #15
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,605

    Re: Speed Vs Readability

    Name:  odbg.png
Views: 82
Size:  23.9 KB



    @TheTrick: ah, OlyDbg 1.0 has the view sources... not sure why 2.0 doesnt. thanks!
    Last edited by DEXWERX; Sep 7th, 2017 at 01:37 PM.
    Imagine what it would be like to set breakpoints in, or step through subclassing code;
    and then being able to hit stop/end/debug or continue, without crashing the IDE.

    VB6.tlb | Bulletproof Subclassing in the IDE (no thunks/assembly/DEP issues)

  16. #16

  17. #17
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    278

    Re: Speed Vs Readability

    Best option for me.
    I know () is superflous, but it's readable.

    Code:
    bFromYN = (UCase$(s) = "Y")

  18. #18
    PowerPoster
    Join Date
    Feb 2012
    Location
    West Virginia
    Posts
    12,182

    Re: Speed Vs Readability

    I haven't tried it but I wonder which of these would be the fastest at runtime?

    Code:
    bFromYN = (UCase$(s) = "Y")
    Code:
    bFromYN = (s= "Y" or s="y")

  19. #19
    Fanatic Member Spooman's Avatar
    Join Date
    Mar 2017
    Posts
    869

    Re: Speed Vs Readability

    My guess is the former.

  20. #20
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,605

    Re: Speed Vs Readability

    turns out this looks much faster as far as code output
    Code:
    bFromYN = (s= "Y" or s="y")
    It just does 2 calls to vbaStrComp on 2 constants.


    where this
    Code:
    bFromYN = (UCase$(s) = "Y")
    translates to a 5 runtime calls (UpperCase, StrMove, StrComp, StrFree, StrFree) and needs exception handling... where for whatever reason the previous routine doesnt.
    Last edited by DEXWERX; Sep 7th, 2017 at 03:10 PM.
    Imagine what it would be like to set breakpoints in, or step through subclassing code;
    and then being able to hit stop/end/debug or continue, without crashing the IDE.

    VB6.tlb | Bulletproof Subclassing in the IDE (no thunks/assembly/DEP issues)

  21. #21
    Fanatic Member
    Join Date
    Feb 2017
    Posts
    642

    Re: Speed Vs Readability

    The fastest seems to be this one:
    Code:
    Private Function bFromYN(s As String) As Boolean
        Dim a As Long
        
        a = Asc(s)
        If (a = 89 Or a = 121) Then bFromYN = True
    End Function
    Test:
    Code:
    Option Explicit
    
    Private Sub Form_Activate()
        Dim c As Long
        Dim iT1
        Dim iMax As Long
        
        
        iMax = 3000000
        Me.AutoRedraw = True
        
        iT1 = Timer
        TOut "1: "
        For c = 1 To iMax
            Call bFromYN1("y")
        Next c
        TOut Int((Timer - iT1) * 1000) / 1000 & vbCrLf
        
        iT1 = Timer
        TOut "2: "
        For c = 1 To iMax
            Call bFromYN2("y")
        Next c
        TOut Int((Timer - iT1) * 1000) / 1000 & vbCrLf
        
        
        iT1 = Timer
        TOut "3: "
        For c = 1 To iMax
            Call bFromYN3("y")
        Next c
        TOut Int((Timer - iT1) * 1000) / 1000 & vbCrLf
        
        iT1 = Timer
        TOut "4: "
        For c = 1 To iMax
            Call bFromYN4("y")
        Next c
        TOut Int((Timer - iT1) * 1000) / 1000 & vbCrLf
        
        iT1 = Timer
        TOut "5: "
        For c = 1 To iMax
            Call bFromYN5("y")
        Next c
        TOut Int((Timer - iT1) * 1000) / 1000 & vbCrLf
        
        iT1 = Timer
        TOut "6: "
        For c = 1 To iMax
            Call bFromYN6("y")
        Next c
        TOut Int((Timer - iT1) * 1000) / 1000 & vbCrLf
        
        iT1 = Timer
        TOut "7: "
        For c = 1 To iMax
            Call bFromYN7("y")
        Next c
        TOut Int((Timer - iT1) * 1000) / 1000 & vbCrLf
    
        iT1 = Timer
        TOut "8: "
        For c = 1 To iMax
            Call bFromYN8("y")
        Next c
        TOut Int((Timer - iT1) * 1000) / 1000 & vbCrLf
    
        iT1 = Timer
        TOut "9: "
        For c = 1 To iMax
            Call bFromYN9("y")
        Next c
        TOut Int((Timer - iT1) * 1000) / 1000 & vbCrLf
    
        iT1 = Timer
        TOut "10: "
        For c = 1 To iMax
            Call bFromYN10("y")
        Next c
        TOut Int((Timer - iT1) * 1000) / 1000 & vbCrLf
    
        iT1 = Timer
        TOut "11: "
        For c = 1 To iMax
            Call bFromYN11("y")
        Next c
        TOut Int((Timer - iT1) * 1000) / 1000 & vbCrLf
    
    End Sub
    
    Private Function bFromYN1(s As String) As Boolean
        If UCase$(s) = "Y" Then bFromYN1 = True
    End Function
    
    Private Function bFromYN2(s As String) As Boolean
        bFromYN2 = UCase$(s) = "Y"
    End Function
    
    Private Function bFromYN3(s As String) As Boolean
        bFromYN3 = (UCase$(s) = "Y")
    End Function
    
    Private Function bFromYN4(s As String) As Boolean
        bFromYN4 = (s = "Y" Or s = "y")
    End Function
    
    Private Function bFromYN5(s As String) As Boolean
        bFromYN5 = s = "Y" Or s = "y"
    End Function
    
    Private Function bFromYN6(s As String) As Boolean
        If s = "Y" Or s = "y" Then bFromYN6 = True
    End Function
    
    Private Function bFromYN7(s As String) As Boolean
        If (s = "Y" Or s = "y") Then bFromYN7 = True
    End Function
    
    Private Function bFromYN8(s As String) As Boolean
        Dim a As Long
        
        a = Asc(s)
        If (a = 89 Or a = 121) Then bFromYN8 = True
    End Function
    
    Private Function bFromYN9(s As String) As Boolean
        Dim a As Long
        
        a = Asc(s)
        bFromYN9 = (a = 89 Or a = 121)
    End Function
    
    Private Function bFromYN10(s As String) As Boolean
        If (Asc(s) = 89 Or Asc(s) = 121) Then bFromYN10 = True
    End Function
    
    
    Private Function bFromYN11(s As String) As Boolean
        Dim b() As Byte
        
        b = s
        If (b(0) = 89 Or b(0) = 121) Then bFromYN11 = True
    End Function
    
    Private Sub TOut(s As String)
        Me.Print s;
        DoEvents
    End Sub
    MSDN online for VB6 - Language Reference - Controls Reference
    Download MSDN October 2001: disk 1, 2 and 3

  22. #22
    Fanatic Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    835

    Re: Speed Vs Readability

    How about this?

    Code:
    Private Function bFromYNJ(s As String) As Boolean
       Select Case Asc(s)
       Case 89, 121
          bFromYNJ = True
       End Select
    End Function

  23. #23
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    3,287

    Re: Speed Vs Readability

    Okay, let's be careful here.

    Asc(s) isn't going to do the same thing as a direct comparison of s. You'd have to do a Len(s)=1 check to make sure it was the same. Otherwise, Asc(s) will just return the ASCII code of the first character.

    Said differently, Asc("asdf") = Asc("a") whereas "asdf" <> "a".

    Just saying,
    Elroy
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  24. #24
    Fanatic Member Spooman's Avatar
    Join Date
    Mar 2017
    Posts
    869

    Re: Speed Vs Readability

    Quote Originally Posted by DEXWERX View Post
    turns out this looks much faster as far as code output
    Code:
    bFromYN = (s= "Y" or s="y")
    I figured the "or" would be the stumbling block.
    Go figure !!

  25. #25
    Fanatic Member
    Join Date
    Feb 2017
    Posts
    642

    Re: Speed Vs Readability

    But as I undestood it is supposed that the function will receive "y", "Y", "n" or "N".
    MSDN online for VB6 - Language Reference - Controls Reference
    Download MSDN October 2001: disk 1, 2 and 3

  26. #26
    Fanatic Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    835

    Re: Speed Vs Readability

    @Eduardo - Elroy makes a good point because Asc("You better not!") will return 89. Asc(Left$(s, 1)) would be safer.

  27. #27
    PowerPoster
    Join Date
    Feb 2006
    Posts
    17,885

    Re: Speed Vs Readability

    Code:
        Dim S As String
    
        S = "œ"
        Debug.Print "S = "; S
        Debug.Print "Asc(S) = "; Asc(S)
        Debug.Print "AscW(S) = "; AscW(S)
    
        S = ChrW$(&H9C&)
        Debug.Print "S = "; S
        Debug.Print "Asc(S) = "; Asc(S)
        Debug.Print "AscW(S) = "; AscW(S)
    For U.S. English locale produces:

    Code:
    S = œ
    Asc(S) =  156 
    AscW(S) =  339 
    S = ?
    Asc(S) =  63 
    AscW(S) =  156

  28. #28
    Fanatic Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    835

    Re: Speed Vs Readability

    Ignore my post re: Asc(Left$( - it doesn't help anything in the case I mentioned. Sometimes it's better not to post at all then to post when distracted!

  29. #29

    Thread Starter
    Lively Member
    Join Date
    Feb 2017
    Posts
    120

    Re: Speed Vs Readability

    Thanks All for Input. Nice to see what others are doing.
    Special Thanks to Trick for taking the time to show use OllyDbg and Results.
    Found both v 2.01 and v 1.10, so downloaded both.

  30. #30
    PowerPoster
    Join Date
    Feb 2012
    Location
    West Virginia
    Posts
    12,182

    Re: Speed Vs Readability

    Quote Originally Posted by DEXWERX View Post
    turns out this looks much faster as far as code output
    Code:
    bFromYN = (s= "Y" or s="y")
    It just does 2 calls to vbaStrComp on 2 constants.


    where this
    Code:
    bFromYN = (UCase$(s) = "Y")
    translates to a 5 runtime calls (UpperCase, StrMove, StrComp, StrFree, StrFree) and needs exception handling... where for whatever reason the previous routine doesnt.
    Interesting, I suspected that the one with the Or statement would be the fastest but did not expect it to be that much different

  31. #31
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    3,287

    Re: Speed Vs Readability

    Okay, a couple more comments on the last few posts. In my eyes, if we're thinking about pure speed, it's always important to think about what VB6 is doing.

    For instance, if we do Left$(s,1), we're almost certainly going to create a second (temporary, internal) string. And manipulating strings is probably one of the slowest things we're talking about here.

    Also, Spoo, an OR operator is going to be extremely fast. An OR instruction is a core CPU machine language instruction.

    Also, it's important to remember our order-of-operation, and to remember the typecast (i.e., variable type) return of various operations. For the order-of-operation, from the MSDN:

    arithmetic operators are evaluated first, comparison operators are evaluated next, and logical operators are evaluated last
    And there's also an order-of-operation within the arithmetic operators (parentheses, exponent, negation, mult & div, mod, add & sub, string concat).

    Therefore, DataMiser's....

    Code:
    bFromYN = (s = "Y" OR s = "y")
    ... will work exactly as we'd like. Furthermore, it doesn't create any temporary strings.

    Also, just to "think through" it a bit, it's going to do the comparisons first (i.e., s = "Y" and also s = "y"). And, the return of each of these operations is going to be of a Boolean type (although temporary, and held in memory, and not shown to us). And next, the OR operator will be executed.

    Now, unbeknownst to many, Boolean types are just a special case of Integer types (two bytes). In binary, False = 0000000000000000, and True = 1111111111111111. Now, an OR operator will operate on any kind of integer (Byte, Integer, Long, Decimal, even LongLong). It's just going to OR the bits. Now, the OR operator is smart enough such that, if both inputs are Boolean, the output will also be Boolean. Therefore, this OR operator will execute lightening fast.

    And then, possibly a few machine language instructions to deal with the parentheses, and make the assignment for the function return.

    I haven't dis-assembled, but I'm thinking this will be, by far, the fastest realization of this test.

    Best Regards,
    Elroy

    EDIT1: Ahhh, and DataMiser snuck a post in on me that actually proves my point.

    EDIT2: That UCase$() is going to be the killer.

    EDIT3: Also, I feel compelled to say again ... I think it's good to have all these understandings. However, when we're trying to "get work done", I think we're better off to just do it the way it comes to us most easily, for the sake of completing our project. If we have a particularly slow spot in some long loop, it's at that time that we can start tweaking for speed.

    EDIT4: Just a "by the way". Yet another example of multiple equal (=) signs being in a single line of code.
    Last edited by Elroy; Sep 7th, 2017 at 05:10 PM.
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  32. #32
    Fanatic Member
    Join Date
    Feb 2017
    Posts
    642

    Re: Speed Vs Readability

    Quote Originally Posted by jpbro View Post
    @Eduardo - Elroy makes a good point because Asc("You better not!") will return 89. Asc(Left$(s, 1)) would be safer.
    You must be aware of the optimization options of the compiler, like to check bounds of an array and so on.
    If you set it to not to check the bounds, you get more speed.

    The functions that one can write also have these tradeoff. Do you want speed or do you want safety?
    If you want speed then don't perform such tests like checking if the string is of one charecter or more.
    But then, you are responsible of not sending anything that the function is not prepared to receive and properly handle.
    If you want the function to be more general, and to be able to handle incorrect entries, then don't expect it to have the best performance.

    It all depends where you'll use the function. If only you will use it and you know the limitations, but you are looking for speed, then it's ok.

    If you are writing a library with a general purpose function that will be used by anyone, then perhaps you'll have to check for incorrect input parameters and raise errors. And document it.
    MSDN online for VB6 - Language Reference - Controls Reference
    Download MSDN October 2001: disk 1, 2 and 3

  33. #33
    Fanatic Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    835

    Re: Speed Vs Readability

    @Eduardo -
    Quote Originally Posted by jpbro View Post
    Ignore my post re: Asc(Left$( - it doesn't help anything in the case I mentioned. Sometimes it's better not to post at all then to post when distracted!


    Curious though if my Select Case example (perhaps with AscW to avoid unicode problems?) will be faster than your OR test.

  34. #34
    Fanatic Member
    Join Date
    Feb 2017
    Posts
    642

    Re: Speed Vs Readability

    Quote Originally Posted by jpbro View Post
    @Eduardo -

    Curious though if my Select Case example (perhaps with AscW to avoid unicode problems?) will be faster than your OR test.
    I tested it, it is almost as fast as the If/Or version, but a few milliseconds slower (in my testing).

    I didn't test with ChrW.
    MSDN online for VB6 - Language Reference - Controls Reference
    Download MSDN October 2001: disk 1, 2 and 3

  35. #35
    Fanatic Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    835

    Re: Speed Vs Readability

    Quote Originally Posted by Eduardo- View Post
    I tested it, it is almost as fast as the If/Or version, but a few milliseconds slower (in my testing).

    I didn't test with ChrW.
    Interesting... I just had a chance to try it here, and Select Case seem significantly faster (tested compiled - ED is the OR test, JP is the Select Case test):

    Name:  2017-09-07_18-38-40.png
Views: 63
Size:  5.5 KB

  36. #36
    Fanatic Member
    Join Date
    Feb 2017
    Posts
    642

    Re: Speed Vs Readability

    Quote Originally Posted by jpbro View Post
    Interesting... I just had a chance to try it here, and Select Case seem significantly faster (tested compiled - ED is the OR test, JP is the Select Case test):

    Name:  2017-09-07_18-38-40.png
Views: 63
Size:  5.5 KB
    Please post the exact code of the test.
    MSDN online for VB6 - Language Reference - Controls Reference
    Download MSDN October 2001: disk 1, 2 and 3

  37. #37
    Fanatic Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    835

    Re: Speed Vs Readability

    Sure, just used your demo and added my code, took out the other tests:

    Code:
    Option Explicit
    
    Private Function bFromYNJ(s As String) As Boolean
       Select Case AscW(s)
       Case 89, 121
          bFromYNJ = True
       End Select
    End Function
    
    Private Function bFromYNE(s As String) As Boolean
        Dim a As Long
        
        a = Asc(s)
        If (a = 89 Or a = 121) Then bFromYNE = True
    End Function
    
    Private Sub Form_Activate()
        Dim c As Long
        Dim iT1
        Dim iMax As Long
        
        
        iMax = 3000000
        Me.AutoRedraw = True
        
        iT1 = Timer
        TOut "ED: "
        For c = 1 To iMax
            Call bFromYNE("y")
        Next c
        TOut Format$(Int((Timer - iT1) * 1000) / 1000, "0.0000") & vbCrLf
        
        iT1 = Timer
        TOut "JP: "
        For c = 1 To iMax
            Call bFromYNJ("y")
        Next c
        TOut Format$(Int((Timer - iT1) * 1000) / 1000, "0.0000") & vbCrLf
        
    End Sub
    
    Private Sub TOut(s As String)
        Me.Print s;
        DoEvents
    End Sub

  38. #38
    Fanatic Member
    Join Date
    Feb 2017
    Posts
    642

    Re: Speed Vs Readability

    OK, I din't remember whether I tested your code compiled before (it seems not), but what I said is true for uncompiled, compiled I get your results also.
    Sorry.

    PS: I think I didn't test it compiled before because with all the others (function versions) I got more or less the same relation between each other compiled and uncompiled.
    MSDN online for VB6 - Language Reference - Controls Reference
    Download MSDN October 2001: disk 1, 2 and 3

  39. #39
    Fanatic Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    835

    Re: Speed Vs Readability

    No need to apologize, glad the mystery is solved

    For timing tests I think it is always important to test compiled.

    I guess part of the mystery remains - why is one faster than the other? I think there are some places to look:

    Asc() returns an Integer in your code, but you are assigning it to a Long. Maybe a conversion takes place and takes time?
    Your IF statement will always perform 2 compares, but the Select Case may only perform 1.

    Maybe someone familiar with debuggers can investigate and find the answer?

  40. #40
    Fanatic Member
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    835

    Re: Speed Vs Readability

    Don't think the Long->Integer conversion would matter...just noticed AscW returns an Integer, so the Select Case would probably be converting that to a Long for its comparison.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width

Survey posted by VBForums.