MID Take two


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 13 of 13

Thread: MID Take two

Hybrid View

  1. #1
    Jay King Guest

    MID Take two

    Mid function I dreamed up for .Net

    Very slow as far as I can tell lol

    Ok what am I doing wrong?
    Private Function sMid(ByVal Str As String, ByVal Position As Int32, ByVal
    Length As Int32) As String

    Dim b() As Byte

    Dim s As String

    Dim h As New System.Text.ASCIIEncoding()

    b = h.ASCII.GetBytes(Str)

    Dim x As Int32

    Dim ch As Char

    Dim sb As StringBuilder

    Position = Position - 1

    For x = Position To ((Position + (Length)) - 1)

    s = s & Chr(b.GetValue(x))

    Next

    Return s

    End Function



  2. #2
    Phil Weber Guest

    Re: MID Take two

    > Ok what am I doing wrong?

    Jay: I'd say this is your problem:

    s = s & Chr(b.GetValue(x))

    It would be much more efficient to use the StringBuilder's .Append method.
    It would be even more efficient to use the String's .CopyTo method to copy
    the desired characters in a single operation. Or simply use .SubString,
    which I suspect is what VB.NET does under the hood:

    Private Function sMid(ByVal Str As String, ByVal Position As Int32, _
    ByVal Length As Int32) As String
    Return Str.Substring(Position, Length)
    End Function

    --
    Phil Weber



  3. #3
    Jason Sobell iGadget Guest

    Re: MID Take two

    Hi,
    If you need to get access at a char level (not byte) your example can be
    rewritten as
    Private Function sMid2(ByVal Str As String, ByVal Position As Int32, ByVal ByValLength As Int32) As String
    Return New String(Str.ToCharArray(Position - 1, ByValLength))
    End Function

    This is much faster than the code you posted, but nowhere near the built-in
    Mid() or SubString() functions.

    Here are some timings for 1 million iterations of
    ret = sMid("This is a test", 7, 4) = 2.60 secs
    ret = Mid$("This is a test", 7, 4) = 0.09 secs
    ret = "This is a test".Substring(7, 4)
    ret = sMid2("This is a test", 7, 4) = 0.40 secs

    Using a longer string exasperates the problems of user defined versions:
    ret = sMid("This is a test, this is a test, and this is a test, and this is a test ", 17, 14) = 8.36 secs
    ret = Mid$("This is a test, this is a test, and this is a test, and this is a test ", 17, 14) = 0.12 secs
    ret = "This is a test, this is a test, and this is a test, and this is a test ".Substring(17, 14) = 0.12 secs
    ret = sMid2("This is a test, this is a test, and this is a test, and this is a test ", 17, 14) = 0.46 secs
    ret = New String("This is a test, this is a test, and this is a test, and this is a test ".ToCharArray(17 - 1, 14)) = 0.46 secs

    As you can see, the loop in your code increases processing time in
    proportion to the length of the substring being requested, but nothing
    comes close to the built-in framework functions.

    Cheers,
    Jason



    On Sat, 25 Jan 2003 08:27:22 -0500, Jay King wrote:

    > Mid function I dreamed up for .Net
    >
    > Very slow as far as I can tell lol
    >
    > Ok what am I doing wrong?
    > Private Function sMid(ByVal Str As String, ByVal Position As Int32, ByVal
    > Length As Int32) As String
    >
    > Dim b() As Byte
    >
    > Dim s As String
    >
    > Dim h As New System.Text.ASCIIEncoding()
    >
    > b = h.ASCII.GetBytes(Str)
    >
    > Dim x As Int32
    >
    > Dim ch As Char
    >
    > Dim sb As StringBuilder
    >
    > Position = Position - 1
    >
    > For x = Position To ((Position + (Length)) - 1)
    >
    > s = s & Chr(b.GetValue(x))
    >
    > Next
    >
    > Return s
    >
    > End Function


  4. #4
    Dave Guest

    Re: MID Take two


    "Phil Weber" <pweber@nospam.fawcette.com> wrote:
    > Private Function sMid(ByVal Str As String, ByVal Position As Int32,

    _
    > ByVal Length As Int32) As String
    > Return Str.Substring(Position, Length)
    > End Function
    >


    Sorry for being petty, but you'd have to use "Str.Substring(Position - 1,
    Length)" since Substring (like everything else truely .NET) uses geeky 0-basing.
    (but it's not faster anyway)

    So if you want to start at what we humans regard as the 3rd position in the
    string, you actually have to suspend common sense and specify the 2nd.

    Geek Olympics:
    0th place: gold
    1st place: silver
    2nd place: bronze

    Geek Career Counselling:
    "Don't jump at the 0th job that comes along"

    Geek Stubborness:
    "If at 0th you don't succeed, try, try again"



  5. #5
    Jay King Guest

    Re: MID Take two

    How would I use append to attach two strings...


    "Phil Weber" <pweber@nospam.fawcette.com> wrote in message
    news:3e329ecb$1@tnews.web.devx.com...
    | > Ok what am I doing wrong?
    |
    | Jay: I'd say this is your problem:
    |
    | s = s & Chr(b.GetValue(x))
    |
    | It would be much more efficient to use the StringBuilder's .Append method.
    | It would be even more efficient to use the String's .CopyTo method to copy
    | the desired characters in a single operation. Or simply use .SubString,
    | which I suspect is what VB.NET does under the hood:
    |
    | Private Function sMid(ByVal Str As String, ByVal Position As Int32, _
    | ByVal Length As Int32) As String
    | Return Str.Substring(Position, Length)
    | End Function
    |
    | --
    | Phil Weber
    |
    |



  6. #6
    Phil Weber Guest

    Re: MID Take two

    > How would I use append to attach two strings?

    Jay:

    sb.Append(String1)
    sb.Append(String2)

    --
    Phil Weber



  7. #7
    Mike Mitchell Guest

    Re: MID Take two

    On Sat, 25 Jan 2003 08:56:59 -0800, "Phil Weber"
    <pweber@nospam.fawcette.com> wrote:

    > > How would I use append to attach two strings?

    >
    >Jay:
    >
    > sb.Append(String1)
    > sb.Append(String2)


    Isn't it more efficient the classic VB way?

    E.g. MyString = MyString & String1 & String2

    The classic VB way is a lot more readable than having to use that
    Append method on each string to be concatenated.

    MM

  8. #8
    Phil Weber Guest

    Re: MID Take two

    > Isn't it more efficient the classic VB way?

    Mike: No. Try timing your concatenation code against Karl Peterson's
    CStringBuilder class: http://www.mvps.org/vb/code/StrBldr.zip
    --
    Phil Weber



  9. #9
    Gary Nelson Guest

    Re: MID Take two

    Jay,

    There is no need for a substitute for the Mid function, it works fine. The
    problem is with the mid statement. That is to say, the one that substitutes
    a series of characters for another series of characters within a string.

    Gary


    > Mid function I dreamed up for .Net
    >
    > Very slow as far as I can tell lol
    >
    > Ok what am I doing wrong?
    > Private Function sMid(ByVal Str As String, ByVal Position As Int32, ByVal
    > Length As Int32) As String
    >
    > Dim b() As Byte
    >
    > Dim s As String
    >
    > Dim h As New System.Text.ASCIIEncoding()
    >
    > b = h.ASCII.GetBytes(Str)
    >
    > Dim x As Int32
    >
    > Dim ch As Char
    >
    > Dim sb As StringBuilder
    >
    > Position = Position - 1
    >
    > For x = Position To ((Position + (Length)) - 1)
    >
    > s = s & Chr(b.GetValue(x))
    >
    > Next
    >
    > Return s
    >
    > End Function
    >
    >




  10. #10
    Patrice Scribe Guest

    Re: MID Take two

    It looks like you are just extracting a string. The problem in .NET is
    actually with *updating* strings. Each time you are updating a string, you
    actually create a brand new string. A StringBuilder may solve this by
    working directly on a string buffer that is allocated one time only for all
    these updates...

    Patrice

    "Jay King" <nemopsj@aol.com> a écrit dans le message de news:
    3e328d91$1@tnews.web.devx.com...
    > Mid function I dreamed up for .Net
    >
    > Very slow as far as I can tell lol
    >
    > Ok what am I doing wrong?
    > Private Function sMid(ByVal Str As String, ByVal Position As Int32, ByVal
    > Length As Int32) As String
    >
    > Dim b() As Byte
    >
    > Dim s As String
    >
    > Dim h As New System.Text.ASCIIEncoding()
    >
    > b = h.ASCII.GetBytes(Str)
    >
    > Dim x As Int32
    >
    > Dim ch As Char
    >
    > Dim sb As StringBuilder
    >
    > Position = Position - 1
    >
    > For x = Position To ((Position + (Length)) - 1)
    >
    > s = s & Chr(b.GetValue(x))
    >
    > Next
    >
    > Return s
    >
    > End Function
    >
    >




  11. #11
    Eddie Burdak Guest

    Re: MID Take two

    Mike,

    Mike Mitchell wrote:
    >> On Sat, 25 Jan 2003 08:56:59 -0800, "Phil Weber"
    >> <pweber@nospam.fawcette.com> wrote:
    >>
    >>>> How would I use append to attach two strings?
    >>>
    >>> Jay:
    >>>
    >>> sb.Append(String1)
    >>> sb.Append(String2)

    >>
    >> Isn't it more efficient the classic VB way?
    >>
    >> E.g. MyString = MyString & String1 & String2
    >>


    Depends on the size of the string. If you have large strings then it
    is painfully slow. Instead you can ovsersize Mystring and start using
    Instr to insert String1 and String2. The performance is improved
    greatly then - but readability can suffer.

    Eddie


  12. #12
    Mike Mitchell Guest

    Re: MID Take two

    On Tue, 28 Jan 2003 08:30:09 +0100, "Eddie Burdak"
    <eburdak@pilatus-aircraft.com> wrote:

    >Depends on the size of the string. If you have large strings then it
    >is painfully slow. Instead you can ovsersize Mystring and start using
    >Instr to insert String1 and String2. The performance is improved
    >greatly then - but readability can suffer.


    Absolutely, Eddie. But in my experience of writing business-type apps
    most strings are quite short - names, addresses, parts, descriptions,
    invoice details and so on. I don't agree (a) that strings should be
    immutable and (b) that strings should be objects.

    MM

  13. #13
    Tom Shelton Guest

    Re: MID Take two


    "Mike Mitchell" <kylix_is@yahoo.co.uk> wrote in message
    news:4kdd3v0bd237hamsq13i09rfqrifsjju0k@4ax.com...
    > On Tue, 28 Jan 2003 08:30:09 +0100, "Eddie Burdak"
    > <eburdak@pilatus-aircraft.com> wrote:
    >
    > >Depends on the size of the string. If you have large strings then it
    > >is painfully slow. Instead you can ovsersize Mystring and start using
    > >Instr to insert String1 and String2. The performance is improved
    > >greatly then - but readability can suffer.

    >
    > Absolutely, Eddie. But in my experience of writing business-type apps
    > most strings are quite short - names, addresses, parts, descriptions,
    > invoice details and so on. I don't agree (a) that strings should be
    > immutable and (b) that strings should be objects.


    First, that may be your experience - but not everyone has the same so it is
    good to be aware of the limitations of VB.CLASSIC string handling and have
    techniques for working around them. As for your other 2 disagreements - B)
    is a matter of religion, and so I'm not going to try to convince you
    otherwise, but there are very good reasons for A. Because the compiler
    knows that a string can not be changed, it is possible to make storage
    optimizations that are not possible for mutable strings - things like
    interning. It does cause opertions that modify strings to suffer - since it
    requires a new allocation with operation - but those are the cases that
    StringBuilder was ment for (StringBuffer in java).

    Tom Shelton



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center