Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > microsoft.public.scripting.vbscript > #11129 > unrolled thread

VbScript and .NET objects

Started bynoone@no.void (Reventlov)
First post2015-08-29 12:40 +0000
Last post2017-03-15 21:38 -0400
Articles 18 — 5 participants

Back to article view | Back to microsoft.public.scripting.vbscript


Contents

  VbScript and .NET objects noone@no.void (Reventlov) - 2015-08-29 12:40 +0000
    Re: VbScript and .NET objects "Mayayana" <mayayana@invalid.nospam> - 2015-08-29 10:39 -0400
      Re: VbScript and .NET objects "Mayayana" <mayayana@invalid.nospam> - 2015-08-29 10:55 -0400
        Re: VbScript and .NET objects GS <gs@v.invalid> - 2015-08-30 12:25 -0400
          Re: VbScript and .NET objects "Mayayana" <mayayana@invalid.nospam> - 2015-08-30 12:55 -0400
            Re: VbScript and .NET objects GS <gs@v.invalid> - 2015-08-30 13:02 -0400
              Re: VbScript and .NET objects GS <gs@v.invalid> - 2015-08-30 13:10 -0400
                Re: VbScript and .NET objects "Mayayana" <mayayana@invalid.nospam> - 2015-08-30 13:42 -0400
                  Re: VbScript and .NET objects GS <gs@v.invalid> - 2015-08-30 14:04 -0400
                    Re: VbScript and .NET objects "Mayayana" <mayayana@invalid.nospam> - 2015-08-30 17:05 -0400
                      Re: VbScript and .NET objects GS <gs@v.invalid> - 2015-08-30 17:14 -0400
            Re: VbScript and .NET objects "Dave \"Crash\" Dummy" <invalid@invalid.invalid> - 2015-08-30 21:45 -0400
              Re: VbScript and .NET objects "Mayayana" <mayayana@invalid.nospam> - 2015-08-30 23:09 -0400
                Re: VbScript and .NET objects "Dave \"Crash\" Dummy" <invalid@invalid.invalid> - 2015-08-31 07:40 -0400
                  Re: VbScript and .NET objects "Mayayana" <mayayana@invalid.nospam> - 2015-08-31 09:50 -0400
      Re: VbScript and .NET objects johnbeschler@gmail.com - 2017-03-15 10:24 -0700
        Re: VbScript and .NET objects "Mayayana" <mayayana@invalid.nospam> - 2017-03-15 14:40 -0400
          Re: VbScript and .NET objects "Mayayana" <mayayana@invalid.nospam> - 2017-03-15 21:38 -0400

#11129 — VbScript and .NET objects

Fromnoone@no.void (Reventlov)
Date2015-08-29 12:40 +0000
SubjectVbScript and .NET objects
Message-ID<55e1a84f.4061562@nntp.aioe.org>
I googled a while looking for new Active/x objects that can be instanced from VbScript.
Most of the .NET objects seem to be in DLLs that can be called with other methods but not
with CreateObject or whatever vb.net uses to connect to its objects.
I have found these examples: 
Some sort of Dictionary with sorting, search, remove, insert.
A string builder with inser/replace methods
A LIFO and a FIFO stack
Any others?



Set DataList = CreateObject ("System.Collections.ArrayList")
DataList.Add "B"
DataList.Add "C"
DataList.Add "E"
DataList.Add "D"
DataList.Add "A"

DataList.Sort()
'Datalist.Reverse() 'Reverse order
'DataList.Remove("D") 'Removes an element

For Each strItem in DataList
    Wscript.Echo strItem
Next

'*******************************************************************************

'Random number between 1 and 100 (1 included, 100 aparently not included)
Set objRandom = CreateObject("System.Random")
Wscript.Echo objRandom.Next_2(1,100)

'*******************************************************************************

'Concatenate strings. Faster than using "&"
set wrt = CreateObject("System.IO.StringWriter")
for i = 1 to 100000
s = CStr(i)
wrt.Write_12 s 'String. Write_11 for decimal, _10 for double, _9 for float
next
s = wrt.GetStringBuilder().ToString()

'*******************************************************************************

set sb = CreateObject("System.Text.StringBuilder")
sb.AppendFormat_5 Nothing, "{0} is a {1} number" & vbCrLf, Array(1, "loneliest")
sb.AppendFormat_5 Nothing, "{0} is a {1} number" & vbCrLf, Array(2, "happiest")
WScript.Echo sb.ToString()  
'Prints:
'1 is a loneliest number
'2 is a happiest number 

'*******************************************************************************

Set s = CreateObject("System.Text.StringBuilder")
s.Append_3 "I love deadlines. I like the whooshing sound they make as they fly by."
s.Append_3 "and the rest."
wscript.echo s.Length
wscript.echo s.Capacity
wscript.echo chr(s.chars(0)) 'returns first char
wscript.echo s.Replace("t", "d").Replace("l", "k").toString
s.Insert_2 7, "insert this " 'after char 7, starting from 1
WScript.Echo s.tostring()
WScript.Echo s.remove(10,4).tostring() 'Removes 4 chars starting from position 10
WScript.Echo s.tostring()
s.clear 'Removes all characters from the stringbuilder instance

'*******************************************************************************
'A sorted dictionary object
'http://www.reliance-scada.com/en/support/articles/technical/vbscript-tip-working-with-an-object-list
Dim Message, SortedList, i, s

' Initializes the message.
Message = ""

' Creates a list.
Set SortedList = CreateObject("System.Collections.SortedList")

' Fills the list.
SortedList.Add "Point", 1
SortedList.Add "Point Cloud", 2
SortedList.Add "Curve", 4
SortedList.Add "Surface", 8
SortedList.Add "Polysurface", 16
SortedList.Add "Mesh", 32

' Returns the element count.
Message = Message & "1: " & SortedList.Count & vbCrLf

' Returns the value by key.
Message = Message & "2: " & SortedList("Surface") & vbCrLf

' Returns the value at the index.
s = ""
For i = 0 To SortedList.Count - 1
  s = s & CStr(SortedList.GetByIndex(i)) & " "
Next
Message = Message & "3: " & s & vbCrLf

' Verifies the existence of the key.
Message = Message & "4: " & SortedList.ContainsKey("Polysurface") & vbCrLf

' Verifies the existence of the value.
Message = Message & "5: " & SortedList.ContainsValue(16) & vbCrLf

' Returns the index of the key (searches for the element by key).
Message = Message & "6: " & SortedList.IndexOfKey("Polysurface") & vbCrLf

' Returns the index of the value (searches for the element by value).
Message = Message & "7: " & SortedList.IndexOfValue(16) & vbCrLf

' Removes the element by key.
SortedList.Remove "Polysurface" & vbCrLf

' Removes the element at the specified index.
SortedList.RemoveAt 0

' Removes all elements.
SortedList.Clear

' Releases the list.
Set SortedList = Nothing

' Displays the result.
MsgBox Message, vbSystemModal 


'*******************************************************************************
'LIFO Last In First Out stack
Dim Message, Stack, Item, s

' Initializes the message.
Message = ""

' Creates a list.
Set Stack = CreateObject("System.Collections.Stack")

' Fills the list.
Stack.Push "Item_1"
Stack.Push "Item_2"
Stack.Push "Item_3"
Stack.Push "Item_4"

' Goes through the list elements.
s = ""
For Each Item In Stack
  s = s & Item & " "
Next
Message = Message & "1: " & s & vbCrLf

' Converts the list into an array.
Message = Message & "2: " & Join(Stack.ToArray, ",") & vbCrLf

' Returns the element count.
Message = Message & "3: " & Stack.Count & vbCrLf

' Verifies the existence of the value.
Message = Message & "4: " & Stack.Contains("Item_2") & vbCrLf

' Removes and returns the last element.
Message = Message & "5: " & Stack.Pop & vbCrLf

' Returns the last element (without removing it).
Message = Message & "6: " & Stack.Peek & vbCrLf

' Empties the list.
Stack.Clear

' Releases the list.
Set Stack = Nothing

' Displays the result.
MsgBox Message, vbSystemModal 


'*******************************************************************************
'FIFO first in first out queue
Dim Message, Queue, Item, s

' Initializes the message.
Message = ""

' Creates a list.
Set Queue = CreateObject("System.Collections.Queue")

' Fills the list.
Queue.Enqueue "Item_1"
Queue.Enqueue "Item_2"
Queue.Enqueue "Item_3"
Queue.Enqueue "Item_4"


' Goes through the list elements.
s = ""
For Each Item In Queue
  s = s & Item & " "
Next
Message = Message & "1: " & s & vbCrLf


' Converts the list into an array.
Message = Message & "2: " & Join(Queue.ToArray, ",") & vbCrLf

' Returns the element count.
Message = Message & "3: " & Queue.Count & vbCrLf

' Verifies the existence of the value.
Message = Message & "4: " & Queue.Contains("Item_2") & vbCrLf

' Removes and returns the first element.
Message = Message & "5: " & Queue.Dequeue & vbCrLf

' Returns the first element (without removing it).
Message = Message & "6: " & Queue.Peek & vbCrLf

' Empties the list.
Queue.Clear

' Releases the list.
Set Queue = Nothing

' Displays the result.
MsgBox Message, vbSystemModal


-- 
Giovanni Cenati (Bergamo, Italy)
Write to "Reventlov" at katamail com
http://digilander.libero.it/Cenati (Esempi e programmi in VbScript)
-- 

[toc] | [next] | [standalone]


#11130

From"Mayayana" <mayayana@invalid.nospam>
Date2015-08-29 10:39 -0400
Message-ID<mrsftt$lp0$1@dont-email.me>
In reply to#11129
  It's never seemed to me that .Net is worth the
trouble. First, it's only useful for private code. There's
no guarantee that people with XP will have .Net
installed.

  Second, I just don't see what's so great. VBS has
Dictionaries. We have arrays. The only thing I really
miss is the mid *statement*, which VB has, allowing
editing of strings without new allocations. But the
Mid statement is essentially the same as building
strings from arrays, which can be done in VBS.
Comparing .Net StringWriter or StringBuilder to
concatenation is a bit like comparing a mediocre
rake to raking your yard with a fork. You need to
compare it fairly, to the best rake you currently have.

 It's *extremely* slow to do:

For i = 1 to 100000
  s = s & "newstring"
Next

  The reason for that is because each iteration requires
allocation of a new string, and the size of that keeps
growing. By the end each iteration is allocating almost
1 MB (or 2 MB for unicode).

  But look at the following tests. Here are my results,
testing StringWriter, StringBuilder and simple VBS array
Join:

Concatenating string of instances
of the word "sample":

Time in seconds for given number of iterations:

                100,000       1,000,000

Stringwriter:   1.25            9.89
StringBuilder:  1.0468        10.6406
VBS array:      0.109375     0.5625

  The results vary slightly with each run, but those
numbers are typical on my machine.
  It's clear from those numbers that a VBS array
far faster. And since the same relative speed holds
up for 100,000 or 1,000,000 iterations, it's clear
that instantiating and releasing the objects is not
a factor in the time required. (However, marshaling
probably is a factor. WScript needs to call into a
separate process for each iteration. As with using
any COM object, that's very inefficient.)
Here's the code, if you want to test it:

Dim s2, T1, T2

T1 = Timer
'TestSW  2
'TestA 2
TestSB 2
T2 = Timer

MsgBox Len(s2) & vbCrLf & CStr(T2 - T1)

Sub TestSW(TestVersion)
   Dim SW, s1, i1, i2
    Set SW = CreateObject("System.IO.StringWriter")
  If TestVersion = 1 Then
    i2 = 100000
  Else
    i2 = 1000000
  End If
s1 = "sample"
 For i1 = 1 to i2
    SW.write_12 s1
 Next

  s2 = SW.GetStringBuilder().ToString()
  Set SW = Nothing
End Sub

Sub TestA(TestVersion)
   Dim A1(), s1, i1, i2

  If TestVersion = 1 Then
    i2 = 100000
  Else
    i2 = 1000000
  End If
  s1 = "sample"
  ReDim A1(i2)
 For i1 = 0 to i2
    A1(i1) = s1
 Next
   s2 = Join(A1, "")
End Sub

Sub TestSB(TestVersion)
  Dim SB, s1, i2, i1
  s1 = "sample"
  Set SB = CreateObject("System.Text.StringBuilder")
  If TestVersion = 1 Then
    i2 = 100000
  Else
    i2 = 1000000
  End If

For i1 = 1 to i2
  SB.Append_3 s1
Next

 s2 = SB.ToString

  Set SB = Nothing
End Sub





[toc] | [prev] | [next] | [standalone]


#11132

From"Mayayana" <mayayana@invalid.nospam>
Date2015-08-29 10:55 -0400
Message-ID<mrsgqv$p51$1@dont-email.me>
In reply to#11130
  Another interesting follow-up to that: I've
found two things that can greatly speed
up complex VBS operations. One is to always
use arrays as string builders for large strings.
The other, not so dramatically efficient but
still worthwhile, is to do case-insensitive search.

Example:
  You have 3 MB of text and need to search
for numerous strings, which may or may not
be the same case. I've found that it's notably
faster to copy to string with something like
s2 = LCase(s)
  Then s2 can be searched using binary search,
while s is still the string operated on:

Pt1 = Instr(1, s2, "apple", 0)
s3 = Mid(s, Pt1, 5)
s3 then returns apple, Apple, APPLE, etc.

  The non-case sensitive version of Instr has to
do a more complex search. The binary version
just needs to look for a matching byte value. 

[toc] | [prev] | [next] | [standalone]


#11133

FromGS <gs@v.invalid>
Date2015-08-30 12:25 -0400
Message-ID<mrvamc$6es$1@dont-email.me>
In reply to#11132
>   Another interesting follow-up to that: I've
> found two things that can greatly speed
> up complex VBS operations. One is to always
> use arrays as string builders for large strings.
> The other, not so dramatically efficient but
> still worthwhile, is to do case-insensitive search.
>
> Example:
>   You have 3 MB of text and need to search
> for numerous strings, which may or may not
> be the same case. I've found that it's notably
> faster to copy to string with something like
> s2 = LCase(s)
>   Then s2 can be searched using binary search,
> while s is still the string operated on:
>
> Pt1 = Instr(1, s2, "apple", 0)
> s3 = Mid(s, Pt1, 5)
> s3 then returns apple, Apple, APPLE, etc.
>
>   The non-case sensitive version of Instr has to
> do a more complex search. The binary version
> just needs to look for a matching byte value. 

How does one implement this in VBS w/o the Mid() function?<g>

-- 
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
  comp.lang.basic.visual.misc
  microsoft.public.vb.general.discussion

[toc] | [prev] | [next] | [standalone]


#11134

From"Mayayana" <mayayana@invalid.nospam>
Date2015-08-30 12:55 -0400
Message-ID<mrvc7v$d91$1@dont-email.me>
In reply to#11133
| > Pt1 = Instr(1, s2, "apple", 0)
| > s3 = Mid(s, Pt1, 5)
| > s3 then returns apple, Apple, APPLE, etc.
| >
| >   The non-case sensitive version of Instr has to
| > do a more complex search. The binary version
| > just needs to look for a matching byte value.
|
| How does one implement this in VBS w/o the Mid() function?<g>
|

  I'm not sure I get that. Are you referring
to my comment about missing the Mid statement
in VBS? As a VBer I expect you probably know
the difference between the Mid statement
and the Mid function. Did I miss something?

  For those who don't know, the Mid statement
can be used to build strings in VB:

Replaces characters in s1, starting with offset 101:

Mid(s1, 101) = "sample"

  It's very efficient because it doesn't require
memory allocation. It just writes the data
directly into the string variable memory. The
equivalent in VBS is something like:

s2 = Left(s1, 100)
s3 = Right(s1, Len(s1) - 106)
s1 = s2 & "sample" & s3

  Three new string allocations. s2, s3 and a
new allocation for s1. Very sloppy and very
slow. Like binary operations, the Mid statment
is a glaring omission in VBS. But using an array
as a string builder comes close to the efficiency
of Mid. 

[toc] | [prev] | [next] | [standalone]


#11135

FromGS <gs@v.invalid>
Date2015-08-30 13:02 -0400
Message-ID<mrvcsk$gj2$1@dont-email.me>
In reply to#11134
>   I'm not sure I get that. Are you referring
> to my comment about missing the Mid statement
> in VBS? As a VBer I expect you probably know
> the difference between the Mid statement
> and the Mid function. Did I miss something?

No.., it's I who missed something! I didn't know there was a Mid 
statement and a Mid() function because I've never used the former. 
Clearly I need to do some homework... (I only know what I use, learning 
as I go thru real world projects!)

-- 
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
  comp.lang.basic.visual.misc
  microsoft.public.vb.general.discussion

[toc] | [prev] | [next] | [standalone]


#11136

FromGS <gs@v.invalid>
Date2015-08-30 13:10 -0400
Message-ID<mrvdbb$ikv$1@dont-email.me>
In reply to#11135
>>   I'm not sure I get that. Are you referring
>> to my comment about missing the Mid statement
>> in VBS? As a VBer I expect you probably know
>> the difference between the Mid statement
>> and the Mid function. Did I miss something?
>
> No.., it's I who missed something! I didn't know there was a Mid 
> statement and a Mid() function because I've never used the former. 
> Clearly I need to do some homework... (I only know what I use, 
> learning as I go thru real world projects!)

Aha! interesting feature! I probably never 'stumbled' onto it due to 
typically using the Replace() function. Now I know.., so thanks for 
pointing this out!

-- 
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
  comp.lang.basic.visual.misc
  microsoft.public.vb.general.discussion

[toc] | [prev] | [next] | [standalone]


#11137

From"Mayayana" <mayayana@invalid.nospam>
Date2015-08-30 13:42 -0400
Message-ID<mrvf0g$prn$1@dont-email.me>
In reply to#11136
| Aha! interesting feature! I probably never 'stumbled' onto it due to
| typically using the Replace() function. Now I know.., so thanks for
| pointing this out!
|

  I've actually found that Replace is also extremely
slow. I'm guessing that it does a version of
concatenation, so I try to avoid it in both script
and VB for large strings.

  A few years back I was writing color syntax
highlighting code for a code editor and a long,
fruitful discussion happened. Mike Williams insisted
that I should build an RTF string from scratch, while
I was using SendMessage API versions of
  RTB.SelStart = x
  RTB.SelLength = y
  RTB.Selcolor = z

  I was sure my way must be fastest. After a lot of
testing I ended up with a far faster method. It turned
out Mike was right. I pointed an integer array at an
LCased version of the string of text in the RTB window
so that I could run a numeric tokenizing routine on
that to add the RTF encoding (like "\cf0 ") for the colors
into a new string using Mid. (So, for instance, the word
Dim might be written to the new string as \cf3 Dim to
make it show a unique color. I don't remember the exact
details of RTF offhand.)

   I later tried other tests, like using only integer
arrays with CopyMemory, but never found anything
faster for ocloring text in an RTB.

  I'm using a VBS approach to that in the JS
De-Ob I linked in the next thread, building a
new string with HTML coloring code by using
an array with Join. Over time I've ended up
doing a lot of very intensive operations in VBS
and had to try to improve them. It's surprising
what speed differences can be attained with
minor changes.

 A bit OT, but do you know this site?

http://www.xbeat.net/vbspeed/

  Interesting stuff for improving speeds in VB. 

[toc] | [prev] | [next] | [standalone]


#11138

FromGS <gs@v.invalid>
Date2015-08-30 14:04 -0400
Message-ID<mrvggj$kj$1@dont-email.me>
In reply to#11137
> A bit OT, but do you know this site?
>
> http://www.xbeat.net/vbspeed/
>
>   Interesting stuff for improving speeds in VB.

No, I don't know about this site but I'll definitely go for a cruise...

Mike has also been very helpful to me in my learning process! Same goes 
for you and many others in the classic VB forums.

Interesting about your syntax coloring! I've been using TextPad with my 
CncFiles Pro app as an optional editor to Notepad for about 10 years 
now. It supports syntax coloring and so when I started shipping it with 
my app I created my own gcode.syn file so it uses standard machine code 
editor colors for key characters/words/flags. Actually, it's pretty 
much the same as any editor used for writing Basic. Only personal 
preference change I made was to color comments light grey so the 
machine code stood out better!

TextPad is written in Pascal (I believe), or some derivitive of it. Its 
syntax files are structured as text-based data files like this...

<snip>
; CNC G-code Syntax File for TextPad
; Author: Garry Sansom
; Last Updated: 5/9/2007

; Colors are default unless specified

; ~Index~
; Keywords1: Reserved Words (all standard keywords used)
; Keywords2: M-Functions		Color:	Teal
; Keywords3: T-Functions			Color:	Olive
; Keywords4: P#### (SubProgram numbers)
; Keywords5: H#-H## (ToolOffset numbers)		Color:	Maroon
; Keywords6: P#-P###, PB#-PB### (Parameter/Variable 
numbers)		Color:	Maroon

; ~Special Assignments~
;    ~(Note that these are unconventional uses)
; PreprocStart: N (PositionLabel)			Color: Silver

; CommentStart: F (FeedRate)		Color:	Teal
; CommentStartAlt: S (SpindleSpeed)		Color:	Fuchsia
; CommentEnd, CommentEndAlt have been assigned a single space character 
so only the assigned character receives color
;
; StringStart:  (  (opening parenthesis for comments)			Color:	Silver
; StringEnd:  )  (closing parenthesis for comments)
</snip>

..which appears to be tab-delimited. Fortunately, TextPad includes full 
instruction for creating/adding our own document classes with their own 
syntax files.<g>

-- 
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
  comp.lang.basic.visual.misc
  microsoft.public.vb.general.discussion

[toc] | [prev] | [next] | [standalone]


#11139

From"Mayayana" <mayayana@invalid.nospam>
Date2015-08-30 17:05 -0400
Message-ID<mrvqsn$bks$1@dont-email.me>
In reply to#11138
| Interesting about your syntax coloring! I've been using TextPad with my
| CncFiles Pro app as an optional editor to Notepad for about 10 years
| now. It supports syntax coloring and so when I started shipping it with
| my app I created my own gcode.syn file so it uses standard machine code
| editor colors for key characters/words/flags. Actually, it's pretty
| much the same as any editor used for writing Basic. Only personal
| preference change I made was to color comments light grey so the
| machine code stood out better!
|

 I seem to remember an OSS control for syntax
coloring being available at one point. They all
seem to take the same approach, though. By
coloring keywords/comments/strings they can
adapt fairly easily to numerous different languages.

  I wrote my own code because I wanted to color
variables, which are more challenging. I find it very
handy in VBS, especially. As long as I declare the
variable it will be colored and the case matched.
That makes it easy to recognize misspellings. I also
like VB6 for the way it will match case for declared
variables and methods, but VB6 never provided the
option to color variables. It only adjusts the case
of them. It has a color for "identifiers", but that's
meaningless. It includes everything that's not a
string, comment or keyword. So it's really just
"code color".


[toc] | [prev] | [next] | [standalone]


#11140

FromGS <gs@v.invalid>
Date2015-08-30 17:14 -0400
Message-ID<mrvrkk$eja$1@dont-email.me>
In reply to#11139
>> Interesting about your syntax coloring! I've been using TextPad with 
>> my CncFiles Pro app as an optional editor to Notepad for about 10 
>> years now. It supports syntax coloring and so when I started 
>> shipping it with my app I created my own gcode.syn file so it uses 
>> standard machine code editor colors for key characters/words/flags. 
>> Actually, it's pretty much the same as any editor used for writing 
>> Basic. Only personal preference change I made was to color comments 
>> light grey so the machine code stood out better!
>> 
>
>  I seem to remember an OSS control for syntax
> coloring being available at one point. They all
> seem to take the same approach, though. By
> coloring keywords/comments/strings they can
> adapt fairly easily to numerous different languages.
>
>   I wrote my own code because I wanted to color
> variables, which are more challenging. I find it very
> handy in VBS, especially. As long as I declare the
> variable it will be colored and the case matched.
> That makes it easy to recognize misspellings. I also
> like VB6 for the way it will match case for declared
> variables and methods, but VB6 never provided the
> option to color variables. It only adjusts the case
> of them. It has a color for "identifiers", but that's
> meaningless. It includes everything that's not a
> string, comment or keyword. So it's really just
> "code color".

Sounds very useful! I now use the x64 edition of TextPad and so I 
suspect it's very .Net under the hood. I do know, though, there are 
lots of non-.Net controls out there for Delphi based apps, both 
x86/x64. I was looking very hard at going with Delphi to replace VB6 so 
I could make x64 apps, leaving VB[A]/VBS only as my main langs. I 
decided to stick with VB6 because I'm too heavily invested in 3rd party 
AX controls, and couldn't justify the cost of replacing them for Delphi 
use. Ok for doing x86 apps but was looking to move to x64 sooner than 
later.

-- 
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
  comp.lang.basic.visual.misc
  microsoft.public.vb.general.discussion

[toc] | [prev] | [next] | [standalone]


#11141

From"Dave \"Crash\" Dummy" <invalid@invalid.invalid>
Date2015-08-30 21:45 -0400
Message-ID<ms0bfn$l4$1@dont-email.me>
In reply to#11134
Mayayana wrote:
> | > Pt1 = Instr(1, s2, "apple", 0)
> | > s3 = Mid(s, Pt1, 5)
> | > s3 then returns apple, Apple, APPLE, etc.
> | >
> | >   The non-case sensitive version of Instr has to
> | > do a more complex search. The binary version
> | > just needs to look for a matching byte value.
> |
> | How does one implement this in VBS w/o the Mid() function?<g>
> |
> 
>   I'm not sure I get that. Are you referring
> to my comment about missing the Mid statement
> in VBS? As a VBer I expect you probably know
> the difference between the Mid statement
> and the Mid function. Did I miss something?
> 
>   For those who don't know, the Mid statement
> can be used to build strings in VB:
> 
> Replaces characters in s1, starting with offset 101:
> 
> Mid(s1, 101) = "sample"
> 
>   It's very efficient because it doesn't require
> memory allocation. It just writes the data
> directly into the string variable memory. The
> equivalent in VBS is something like:
> 
> s2 = Left(s1, 100)
> s3 = Right(s1, Len(s1) - 106)
> s1 = s2 & "sample" & s3
> 
>   Three new string allocations. s2, s3 and a
> new allocation for s1. Very sloppy and very
> slow. Like binary operations, the Mid statment
> is a glaring omission in VBS. But using an array
> as a string builder comes close to the efficiency
> of Mid. 

I use the Mid function to emulate the lacking Mid statement:

s1=mid(s1,1,100) & "sample" & mid(s1,101)

As always in VBS, there are several ways to perform a task. Not 
recommended, but works:

s1=replace(s1,left(s1,100),left(s1,100) & "sample",1,1)

-- 
Crash

Registered pedophobe

[toc] | [prev] | [next] | [standalone]


#11142

From"Mayayana" <mayayana@invalid.nospam>
Date2015-08-30 23:09 -0400
Message-ID<ms0g7v$7pk$1@dont-email.me>
In reply to#11141
| I use the Mid function to emulate the lacking Mid statement:
|
| s1=mid(s1,1,100) & "sample" & mid(s1,101)
|

  That doesn't improve efficiency over the Left/Right code.
It's just another way to do the same thing. You're still
allocating 2 new strings, even though you're not declaring
them, and then concatenating those strings in a 3rd new
string. There is no substitute for the Mid statement, which
is an entirely different operation, writing directly to the
string bytes with no new allocations.

  Any of the Mid/Left/Right/Replace methods is fine for
small string operations, but for extensive operations it's
worthwhile to try to find a way to do it with Array/Join.


[toc] | [prev] | [next] | [standalone]


#11143

From"Dave \"Crash\" Dummy" <invalid@invalid.invalid>
Date2015-08-31 07:40 -0400
Message-ID<ms1ebk$3n3$1@dont-email.me>
In reply to#11142
Mayayana wrote:
> | I use the Mid function to emulate the lacking Mid statement:
> |
> | s1=mid(s1,1,100) & "sample" & mid(s1,101)
> |
> 
>   That doesn't improve efficiency over the Left/Right code.
> It's just another way to do the same thing. You're still
> allocating 2 new strings, even though you're not declaring
> them, and then concatenating those strings in a 3rd new
> string. There is no substitute for the Mid statement, which
> is an entirely different operation, writing directly to the
> string bytes with no new allocations.
> 
>   Any of the Mid/Left/Right/Replace methods is fine for
> small string operations, but for extensive operations it's
> worthwhile to try to find a way to do it with Array/Join.

I don't understand how you turn the initial string of x characters into 
an array of x elements.
-- 
Crash

A line in the sand doesn't mean much if it disappears at high tide.

[toc] | [prev] | [next] | [standalone]


#11144

From"Mayayana" <mayayana@invalid.nospam>
Date2015-08-31 09:50 -0400
Message-ID<ms1lq7$1v3$1@dont-email.me>
In reply to#11143
| I don't understand how you turn the initial string of x characters into
| an array of x elements.

   It depends on what you're doing. If you look at the
JS De-ob coloring routine I linked you can see that
it's building a new string, avoiding concatenation,
which would be unworkable on such a large scale.
I need to rebuild the string almost character by
character, and it needs to work within a reasonable
amount of time on, say, 100 KB of script.

  If you want to parse a string and
add lots of substrings then the fastest method is
to parse the string non-case-sensitive and then build
the new one in an array. You can't use an array for
everything, but you can use it for many things where
one might have used the Mid statement.

  For a single replacement it doesn't really matter,
but anyplace where you're doing multiple string
allocations, time can get wasted on a very large
scale.

  Replace is surprisingly inefficient on large strings,
for the same reasons, so I try to use Replace only
on small strings and use array string-builders for
the big strings.

  I originally got this from VB. Matthew Curland, one
of the original VB developers. He explained in his book
that Join walks the array, measuring everything, and
then only needs to allocate one big string.

  In the samples below, I take a string full of "a"
and replace 6 characters at a time with "sample",
using Mid, Left/Right, or an array. The array just
assigns "sample" to each array index and then calls
Join. It's not really a real-world test, but it
demonstrates the point. My results in seconds:

string length:
          100,000     300,000     1,000,000

Mid      .89             51.2

LR       .843            50.51       718.812

Array   .015            .046        .18

  While L/R was fairly quick with a string
100,000 characters long, as you can see,
it gets crazy inefficient as it gets longer.
Almost 12 minutes for a string 1,000,000
characters long! The big drain is when it
needs to allocate big strings in every iteration.

  I changed the test to 300,000 from 1,000,000
after the LR test, so I wouldn't be here all morning!
That's why I have no results for a test of Mid on
a string 1,000,000 characters long.
   But with the array, the length of the string
hardly matters because there is only one
large string allocation. Here's the code:

Dim s2, T1, T2

T1 = Timer
'TestMid 2
'TestLR 2
TestA1  2
T2 = Timer


MsgBox Len(s2) & vbCrLf & CStr(T2 - T1)
MsgBox s2

Sub TestMid(TestVersion)
   Dim s1, i1, i2
  If TestVersion = 1 Then
    i2 = 100000
  Else
    i2 = 300000
  End If
s1 = "sample"
s2 = String(i2, "a")

i1 = 10
Do While i1 < (i2 - 10)
  s2 = mid(s2, 1, i1) & s1 & mid(s2, i1 + 7)
  i1 = i1 + 6
Loop

End Sub

Sub TestA1(TestVersion)
   Dim A1(), s1, i1, i2
  If TestVersion = 1 Then
    i2 = 100000
  Else
    i2 = 300000
  End If
s1 = "sample"

  ReDim A1(i2 \ 6)
    For i1 = 0 to UBound(A1)
      A1(i1) = s1
    Next

    s2 = Join(A1, "")
End Sub

Sub TestLR(TestVersion)
   Dim s1, i1, i2
  If TestVersion = 1 Then
    i2 = 100000
  Else
    i2 = 300000
  End If
s1 = "sample"
s2 = String(i2, "a")

i1 = 10
Do While i1 < (i2 - 10)
  s2 = Left(s2, i1) & s1 & Right(s2, Len(s2) - (i1 + 6))
  i1 = i1 + 6
Loop

End Sub

[toc] | [prev] | [next] | [standalone]


#11587

Fromjohnbeschler@gmail.com
Date2017-03-15 10:24 -0700
Message-ID<aba91193-4e25-4433-9610-524fda5dee28@googlegroups.com>
In reply to#11130
IMHO you are not doing a fair comparison. 

When using Redim in VBS, you do not always know ahead of time how many iterations.

So, the correct way to do your test with VBS arrays should be like below because you need to redim the array each time you add to it.

Sub TestAR(TestVersion) 
	Dim A1(), s1, i1, i2 

	If TestVersion = 1 Then 
		i2 = 100000 
	Else 
		i2 = 1000000 
	End If 
	s1 = "sample" 
	'ReDim A1(i2) 
	For i1 = 0 to i2 
		Redim Preserve A1(i1)
		A1(i1) = s1 
	Next 
	s2 = Join(A1, "") 
End Sub 

If you do the test that way, the array method is FAR slower:


TestSW 1: 600000 0.5625
TestA 1: 600006 0.0234375
TestAR 1: 600006 0.2226563
TestSB 1: 600000 0.4882813
TestSW 2: 6000000 5.265625
TestA 2: 6000006 0.2265625
TestAR 2: 6000006 24.03125<----------------------
TestSB 2: 6000000 4.792969

Jus sayin :)




On Saturday, August 29, 2015 at 9:36:26 AM UTC-5, Mayayana wrote:
> It's never seemed to me that .Net is worth the
> trouble. First, it's only useful for private code. There's
> no guarantee that people with XP will have .Net
> installed.
> 
>   Second, I just don't see what's so great. VBS has
> Dictionaries. We have arrays. The only thing I really
> miss is the mid *statement*, which VB has, allowing
> editing of strings without new allocations. But the
> Mid statement is essentially the same as building
> strings from arrays, which can be done in VBS.
> Comparing .Net StringWriter or StringBuilder to
> concatenation is a bit like comparing a mediocre
> rake to raking your yard with a fork. You need to
> compare it fairly, to the best rake you currently have.
> 
>  It's *extremely* slow to do:
> 
> For i = 1 to 100000
>   s = s & "newstring"
> Next
> 
>   The reason for that is because each iteration requires
> allocation of a new string, and the size of that keeps
> growing. By the end each iteration is allocating almost
> 1 MB (or 2 MB for unicode).
> 
>   But look at the following tests. Here are my results,
> testing StringWriter, StringBuilder and simple VBS array
> Join:
> 
> Concatenating string of instances
> of the word "sample":
> 
> Time in seconds for given number of iterations:
> 
>                 100,000       1,000,000
> 
> Stringwriter:   1.25            9.89
> StringBuilder:  1.0468        10.6406
> VBS array:      0.109375     0.5625
> 
>   The results vary slightly with each run, but those
> numbers are typical on my machine.
>   It's clear from those numbers that a VBS array
> far faster. And since the same relative speed holds
> up for 100,000 or 1,000,000 iterations, it's clear
> that instantiating and releasing the objects is not
> a factor in the time required. (However, marshaling
> probably is a factor. WScript needs to call into a
> separate process for each iteration. As with using
> any COM object, that's very inefficient.)
> Here's the code, if you want to test it:
> 
> Dim s2, T1, T2
> 
> T1 = Timer
> 'TestSW  2
> 'TestA 2
> TestSB 2
> T2 = Timer
> 
> MsgBox Len(s2) & vbCrLf & CStr(T2 - T1)
> 
> Sub TestSW(TestVersion)
>    Dim SW, s1, i1, i2
>     Set SW = CreateObject("System.IO.StringWriter")
>   If TestVersion = 1 Then
>     i2 = 100000
>   Else
>     i2 = 1000000
>   End If
> s1 = "sample"
>  For i1 = 1 to i2
>     SW.write_12 s1
>  Next
> 
>   s2 = SW.GetStringBuilder().ToString()
>   Set SW = Nothing
> End Sub
> 
> Sub TestA(TestVersion)
>    Dim A1(), s1, i1, i2
> 
>   If TestVersion = 1 Then
>     i2 = 100000
>   Else
>     i2 = 1000000
>   End If
>   s1 = "sample"
>   ReDim A1(i2)
>  For i1 = 0 to i2
>     A1(i1) = s1
>  Next
>    s2 = Join(A1, "")
> End Sub
> 
> Sub TestSB(TestVersion)
>   Dim SB, s1, i2, i1
>   s1 = "sample"
>   Set SB = CreateObject("System.Text.StringBuilder")
>   If TestVersion = 1 Then
>     i2 = 100000
>   Else
>     i2 = 1000000
>   End If
> 
> For i1 = 1 to i2
>   SB.Append_3 s1
> Next
> 
>  s2 = SB.ToString
> 
>   Set SB = Nothing
> End Sub

[toc] | [prev] | [next] | [standalone]


#11588

From"Mayayana" <mayayana@invalid.nospam>
Date2017-03-15 14:40 -0400
Message-ID<oac1ll$cvj$1@dont-email.me>
In reply to#11587
<johnbeschler@gmail.com> wrote

| When using Redim in VBS, you do not always know ahead of time how many 
iterations.
|

  That's true. But in usage that's not very relevant.
Your version is not something any experienced scripter
would do. It's not a sensible design. It's just a demo
of the cost of Redim.

  In most cases you will know the number of items,
or at least the possible upper limit. In those cases
the typical method is to start with a Redim that's
ample to hold the highest possible number. In cases
where that's not feasible, I estimate, like so:

' we know there are at least 100000 items, but
' we don't know how many total.

UB = 100000
Redim A1(UB)
 i = 0
For i = 0 to unknown-number
   A1(i) = x
   if i = ub then
     ub = ub + 100000
     Redim Preserve a1(ub)
   end if
next

 There's then a final Redim Preserve A1(unknown-number)

  That's realistic usage. I've done it many times. I
generally have an idea of the range, at least, so I
know whether to redim every 1000 or every 100000.


   Testing 6 million writes seems a bit silly to me.
I've never needed to do such a thing. But that
was your test. To give .Net a headstart I even
made a poor prediction of the toital size, requiring
me to do 60 Redim Preserve. In real usage
I probably would have known the total was over
1 million. This is my result:

6 million iterations
string length of 36,000,000

String Builder                                  61.56 seconds

String Writer                                  67.34 seconds

VBS array knowing total items           3.375 seconds

VBS array having only a vague
 idea of total items                          6.156 seconds

  So .Net is still pointless bloatware.

  Also, you're posting about 5 months late. I'm guessing
you're using Google Groups. I suggest you get a real
newsreader. It works better for newsgroups and you'll
be able to take part in current discussions rather than
posting willy nilly to long-gone threads.

 Here's the code for my second version:

Sub TestA(TestVersion)
 Dim A1(), s1, i1, i2, UB

 If TestVersion = 1 Then
 i2 = 100000
 Else
 i2 = 6000000
 End If
 s1 = "sample"
UB = 100000
 ReDim A1(i2)
 For i1 = 0 to i2
       A1(i1) = s1
       If i1 = UB Then
          UB = UB + 100000
          ReDim Preserve A1(UB)
       End If
 Next
   ReDim Preserve A1(i2)
 s2 = Join(A1, "")
 End Sub


--------------------------------------------------------------
| So, the correct way to do your test with VBS arrays should be like below 
because you need to redim the array each time you add to it.
|
| Sub TestAR(TestVersion)
| Dim A1(), s1, i1, i2
|
| If TestVersion = 1 Then
| i2 = 100000
| Else
| i2 = 1000000
| End If
| s1 = "sample"
| 'ReDim A1(i2)
| For i1 = 0 to i2
| Redim Preserve A1(i1)
| A1(i1) = s1
| Next
| s2 = Join(A1, "")
| End Sub
|
| If you do the test that way, the array method is FAR slower:
|
|
| TestSW 1: 600000 0.5625
| TestA 1: 600006 0.0234375
| TestAR 1: 600006 0.2226563
| TestSB 1: 600000 0.4882813
| TestSW 2: 6000000 5.265625
| TestA 2: 6000006 0.2265625
| TestAR 2: 6000006 24.03125<----------------------
| TestSB 2: 6000000 4.792969
|
| Jus sayin :)
|
|
|
|
| On Saturday, August 29, 2015 at 9:36:26 AM UTC-5, Mayayana wrote:
| > It's never seemed to me that .Net is worth the
| > trouble. First, it's only useful for private code. There's
| > no guarantee that people with XP will have .Net
| > installed.
| >
| >   Second, I just don't see what's so great. VBS has
| > Dictionaries. We have arrays. The only thing I really
| > miss is the mid *statement*, which VB has, allowing
| > editing of strings without new allocations. But the
| > Mid statement is essentially the same as building
| > strings from arrays, which can be done in VBS.
| > Comparing .Net StringWriter or StringBuilder to
| > concatenation is a bit like comparing a mediocre
| > rake to raking your yard with a fork. You need to
| > compare it fairly, to the best rake you currently have.
| >
| >  It's *extremely* slow to do:
| >
| > For i = 1 to 100000
| >   s = s & "newstring"
| > Next
| >
| >   The reason for that is because each iteration requires
| > allocation of a new string, and the size of that keeps
| > growing. By the end each iteration is allocating almost
| > 1 MB (or 2 MB for unicode).
| >
| >   But look at the following tests. Here are my results,
| > testing StringWriter, StringBuilder and simple VBS array
| > Join:
| >
| > Concatenating string of instances
| > of the word "sample":
| >
| > Time in seconds for given number of iterations:
| >
| >                 100,000       1,000,000
| >
| > Stringwriter:   1.25            9.89
| > StringBuilder:  1.0468        10.6406
| > VBS array:      0.109375     0.5625
| >
| >   The results vary slightly with each run, but those
| > numbers are typical on my machine.
| >   It's clear from those numbers that a VBS array
| > far faster. And since the same relative speed holds
| > up for 100,000 or 1,000,000 iterations, it's clear
| > that instantiating and releasing the objects is not
| > a factor in the time required. (However, marshaling
| > probably is a factor. WScript needs to call into a
| > separate process for each iteration. As with using
| > any COM object, that's very inefficient.)
| > Here's the code, if you want to test it:
| >
| > Dim s2, T1, T2
| >
| > T1 = Timer
| > 'TestSW  2
| > 'TestA 2
| > TestSB 2
| > T2 = Timer
| >
| > MsgBox Len(s2) & vbCrLf & CStr(T2 - T1)
| >
| > Sub TestSW(TestVersion)
| >    Dim SW, s1, i1, i2
| >     Set SW = CreateObject("System.IO.StringWriter")
| >   If TestVersion = 1 Then
| >     i2 = 100000
| >   Else
| >     i2 = 1000000
| >   End If
| > s1 = "sample"
| >  For i1 = 1 to i2
| >     SW.write_12 s1
| >  Next
| >
| >   s2 = SW.GetStringBuilder().ToString()
| >   Set SW = Nothing
| > End Sub
| >
| > Sub TestA(TestVersion)
| >    Dim A1(), s1, i1, i2
| >
| >   If TestVersion = 1 Then
| >     i2 = 100000
| >   Else
| >     i2 = 1000000
| >   End If
| >   s1 = "sample"
| >   ReDim A1(i2)
| >  For i1 = 0 to i2
| >     A1(i1) = s1
| >  Next
| >    s2 = Join(A1, "")
| > End Sub
| >
| > Sub TestSB(TestVersion)
| >   Dim SB, s1, i2, i1
| >   s1 = "sample"
| >   Set SB = CreateObject("System.Text.StringBuilder")
| >   If TestVersion = 1 Then
| >     i2 = 100000
| >   Else
| >     i2 = 1000000
| >   End If
| >
| > For i1 = 1 to i2
| >   SB.Append_3 s1
| > Next
| >
| >  s2 = SB.ToString
| >
| >   Set SB = Nothing
| > End Sub
| 

[toc] | [prev] | [next] | [standalone]


#11589

From"Mayayana" <mayayana@invalid.nospam>
Date2017-03-15 21:38 -0400
Message-ID<oacq66$u4v$1@dont-email.me>
In reply to#11588
"Mayayana" <mayayana@invalid.nospam> wrote

Woops. I had a typo in my code sample.

UB = 100000
 ReDim A1(i2)

  should have been

UB = 100000
Redim A1(UB)

  So that the array would start out at 100000.
The way I had written it the array started out
full size (6 million) and didn't need to be redimmed.
That was the same as my original code that you
questioned.

  Interestingly, I get almost the exact same
result with 60 Redim Preserve as I did with a
single Redim. The time was 6.187 seconds.

   I think what this demonstrates is just how
wasteful it is to concatenate repeatedly. But
joining an array is quick. An array is a natural
string builder. With concatenation or the method
you suggested, there will be 6 million
allocations of memory. With Redim A1(6000000)
there's only one allocation. With the gradual
building, 100K at a time, there are 60 allocations,
which is still a very small number.

   I expect the .Net methods are probably not too
inefficient, once they get going. But .Net itself
is a pig and none of it is known for speed. Like
Java, that's not the intended strength of .Net.
Rather, sandboxing and  ease of coding are the
intention. If .Net provided things that script can't
do, like a window component or maybe graphics
functions, that would be different. Unfortunately,
.Net breaks COM, making it mainly incompatible with
VBS. (What the heck were the Microsofties thinking
with that decision?!) As far as I know, .Net offers
nothing of value to script to offset the disadvantage
and sheer distastefulness of loading a barrel of slop
in order to run a script.


[toc] | [prev] | [standalone]


Back to top | Article view | microsoft.public.scripting.vbscript


csiph-web