How to dynamically resize an array?

M

Michael Williams

Herfried K. Wagner said:
Well, for sure it's easier to add the 'Preserve' keyword, but
note that resizing the array in every iteration of the loop
will reduce the performance significantly . . .

Are you a complete dick head, Wagner? The man said that he will resize the
array once! Besides, even if he does want to resize it more than once he
very definitely never said that he was goiung to resize it at every
iteration of the loop. Once again you're making things up and putting words
into other people's mouths simply so that you can sound off and make
yourself feel more important than you actually are.
 
H

Herfried K. Wagner [MVP]

Michael Williams said:
Well, for sure it's easier to add the 'Preserve' keyword, but
note that resizing the array in every iteration of the loop
will reduce the performance significantly . . .

Are you a complete [...]? The man said that he will resize the array once!
Besides, even if he does want to resize it more than once he very
definitely never said that he was goiung to resize it at every iteration
of the loop.

Obviously you didn't even take a look at the OP's initial message. In the
code fragment he posted there the array's size is increased by one in each
iteration. As a reply to my answer he wrote:

| Since I only need to resize the array once during
| Form.Load Preserve will be fine and easier to write
| into the code I`ve already written.

I wonder how the code the OP finally came up with looks like. At least
based on what the OP has written I assume he simply changed 'ReDim' to
'ReDim Preserve', which would have led to the solution suffering from a huge
performance problem I mentioned.
 
H

Herfried K. Wagner [MVP]

Michael Williams said:
Well, for sure it's easier to add the 'Preserve' keyword, but
note that resizing the array in every iteration of the loop
will reduce the performance significantly . . .

Are you a complete [...]? The man said that he will resize the array once!
Besides, even if he does want to resize it more than once he very
definitely never said that he was goiung to resize it at every iteration
of the loop.

Obviously you didn't even take a look at the OP's initial message. In the
code fragment he posted there the array's size is increased by one in each
iteration. As a reply to my answer he wrote:

| Since I only need to resize the array once during
| Form.Load Preserve will be fine and easier to write
| into the code I`ve already written.

I wonder how the code the OP finally came up with looks like. At least
based on what the OP has written I assume he simply changed 'ReDim' to
'ReDim Preserve', which would have led to the solution suffering from a huge
performance problem I mentioned.
 
R

roidy

Thanks to everyone for the input, but the example I gave was just to get the
point across that I needed to resize an array. My actual program is more
complicated and deals with reading and storing xml data. The program is for
reading in TV series and episode data from theTVDB.com and tagging groups of
mp4 files with iTunes style metadata(hence my posts regarding libmp4v2.dll).
The program reads in a xml file that contains an unknown number of episodes
from a TV series hence my need to be able to resize an array.

My program uses two structures:-

Structure Series
Dim Name As String
Dim ID As Integer
Dim Season As Integer
Dim Episode() As Episode
Dim ArtFile As String
Dim NoOfEpisodes As Integer
End Structure

Structure Episode
Dim FileName As String
Dim Title As String
Dim Airdate As String
Dim Number As Integer
Dim HD As Boolean
Dim Description As String
End Structure

There is probably a much better way to manage the data but this works fine
for my application.

Rob
 
R

roidy

Thanks to everyone for the input, but the example I gave was just to get the
point across that I needed to resize an array. My actual program is more
complicated and deals with reading and storing xml data. The program is for
reading in TV series and episode data from theTVDB.com and tagging groups of
mp4 files with iTunes style metadata(hence my posts regarding libmp4v2.dll).
The program reads in a xml file that contains an unknown number of episodes
from a TV series hence my need to be able to resize an array.

My program uses two structures:-

Structure Series
Dim Name As String
Dim ID As Integer
Dim Season As Integer
Dim Episode() As Episode
Dim ArtFile As String
Dim NoOfEpisodes As Integer
End Structure

Structure Episode
Dim FileName As String
Dim Title As String
Dim Airdate As String
Dim Number As Integer
Dim HD As Boolean
Dim Description As String
End Structure

There is probably a much better way to manage the data but this works fine
for my application.

Rob
 
R

roidy

Hi Herfried, the example I gave was just to get across the point that I need
to resize an array the actual code is for reading in a xml file:-

Dim reader As XmlTextReader = New XmlTextReader( _
"http://www.thetvdb.com/api/
_
GetSeries.php?seriesname="
& _
search_SeriesName.Text)
Do While (reader.Read())
Select Case reader.NodeType
Case XmlNodeType.Element
Select Case reader.Name
Case "Series"
lp = lp + 1
ReDim Preserve MySearch.Results(lp)
Case "seriesid"
MySearch.Results(lp).SeriesID =
CInt(reader.ReadString())
Case "SeriesName"
MySearch.Results(lp).SeriesName = reader.ReadString()
search_SeriesNameList.Items.Add(MySearch.Results(lp). _

SeriesName)
Case "Overview"
MySearch.Results(lp).SeriesDesc = reader.ReadString()
End Select
End Select
Loop

Everytime I hit a new "Series" element in the xml file I need to increase
the size of the Results array by one. I don`t know how many "Series"
elements the xml file contains until it is read from beginning to end. Speed
isn`t important because the whole function only runs once and I predict that
the array will be ReDim`ed no more that 20-25 times.

Rob


Herfried K. Wagner said:
Michael Williams said:
Since I only need to resize the array once during Form.Load
Preserve will be fine and easier to write into the code I`ve already
written.

Well, for sure it's easier to add the 'Preserve' keyword, but
note that resizing the array in every iteration of the loop
will reduce the performance significantly . . .

Are you a complete [...]? The man said that he will resize the array
once! Besides, even if he does want to resize it more than once he very
definitely never said that he was goiung to resize it at every iteration
of the loop.

Obviously you didn't even take a look at the OP's initial message. In the
code fragment he posted there the array's size is increased by one in each
iteration. As a reply to my answer he wrote:

| Since I only need to resize the array once during
| Form.Load Preserve will be fine and easier to write
| into the code I`ve already written.

I wonder how the code the OP finally came up with looks like. At least
based on what the OP has written I assume he simply changed 'ReDim' to
'ReDim Preserve', which would have led to the solution suffering from a
huge performance problem I mentioned.
 
R

roidy

Hi Herfried, the example I gave was just to get across the point that I need
to resize an array the actual code is for reading in a xml file:-

Dim reader As XmlTextReader = New XmlTextReader( _
"http://www.thetvdb.com/api/
_
GetSeries.php?seriesname="
& _
search_SeriesName.Text)
Do While (reader.Read())
Select Case reader.NodeType
Case XmlNodeType.Element
Select Case reader.Name
Case "Series"
lp = lp + 1
ReDim Preserve MySearch.Results(lp)
Case "seriesid"
MySearch.Results(lp).SeriesID =
CInt(reader.ReadString())
Case "SeriesName"
MySearch.Results(lp).SeriesName = reader.ReadString()
search_SeriesNameList.Items.Add(MySearch.Results(lp). _

SeriesName)
Case "Overview"
MySearch.Results(lp).SeriesDesc = reader.ReadString()
End Select
End Select
Loop

Everytime I hit a new "Series" element in the xml file I need to increase
the size of the Results array by one. I don`t know how many "Series"
elements the xml file contains until it is read from beginning to end. Speed
isn`t important because the whole function only runs once and I predict that
the array will be ReDim`ed no more that 20-25 times.

Rob


Herfried K. Wagner said:
Michael Williams said:
Since I only need to resize the array once during Form.Load
Preserve will be fine and easier to write into the code I`ve already
written.

Well, for sure it's easier to add the 'Preserve' keyword, but
note that resizing the array in every iteration of the loop
will reduce the performance significantly . . .

Are you a complete [...]? The man said that he will resize the array
once! Besides, even if he does want to resize it more than once he very
definitely never said that he was goiung to resize it at every iteration
of the loop.

Obviously you didn't even take a look at the OP's initial message. In the
code fragment he posted there the array's size is increased by one in each
iteration. As a reply to my answer he wrote:

| Since I only need to resize the array once during
| Form.Load Preserve will be fine and easier to write
| into the code I`ve already written.

I wonder how the code the OP finally came up with looks like. At least
based on what the OP has written I assume he simply changed 'ReDim' to
'ReDim Preserve', which would have led to the solution suffering from a
huge performance problem I mentioned.
 
R

roidy

NoOfEpisodes is unknown until the episodes have read in one by one from the
xml file. In the previous version of the program I just gave the array a
large value eg. 40 as it is unlikely any season of a TV series will have
that many episodes. I`m just tidying the program up and it seemed wasteful
to declare an array that large when it probably isn`t needed. The only other
way would be to read the xml file twice, firstly counting the number of
episodes and then declaring the array, and then read it again and fetch in
the episode data.

Rob
 
R

roidy

NoOfEpisodes is unknown until the episodes have read in one by one from the
xml file. In the previous version of the program I just gave the array a
large value eg. 40 as it is unlikely any season of a TV series will have
that many episodes. I`m just tidying the program up and it seemed wasteful
to declare an array that large when it probably isn`t needed. The only other
way would be to read the xml file twice, firstly counting the number of
episodes and then declaring the array, and then read it again and fetch in
the episode data.

Rob
 
B

Branco

roidy said:
Hi Herfried, the example I gave was just to get across the point that I need
to resize an array the actual code is for reading in a xml file:-
Everytime I hit a new "Series" element in the xml file I need to increase
the size of the Results array by one. I don`t know how many "Series"
elements the xml file contains until it is read from beginning to end. Speed
isn`t important because the whole function only runs once and I predict that
the array will be ReDim`ed no more that 20-25 times.

Even though you are redimmensioning the array just a few times,
consider the advice to use a generic List(Of YourClassNameHere)
instead of an Array as if you were having soup with a fork and someone
was telling you to use a spoon. Yes, you can have the soup with a
fork, and nobody will question that if they know you (strangers my
find you -- actually your code -- suspicious, though =)). But the best
-- I even dare to say "the correct" -- way to have the soup is to use
a spoon. In this case, a generic list class.

best regards,

Branco.
 
B

Branco

roidy said:
Hi Herfried, the example I gave was just to get across the point that I need
to resize an array the actual code is for reading in a xml file:-
Everytime I hit a new "Series" element in the xml file I need to increase
the size of the Results array by one. I don`t know how many "Series"
elements the xml file contains until it is read from beginning to end. Speed
isn`t important because the whole function only runs once and I predict that
the array will be ReDim`ed no more that 20-25 times.

Even though you are redimmensioning the array just a few times,
consider the advice to use a generic List(Of YourClassNameHere)
instead of an Array as if you were having soup with a fork and someone
was telling you to use a spoon. Yes, you can have the soup with a
fork, and nobody will question that if they know you (strangers my
find you -- actually your code -- suspicious, though =)). But the best
-- I even dare to say "the correct" -- way to have the soup is to use
a spoon. In this case, a generic list class.

best regards,

Branco.
 
M

Mike

roidy said:
NoOfEpisodes is unknown until the episodes have read in one by one from
the xml file. In the previous version of the program I just gave the
array a large value eg. 40 as it is unlikely any season of a TV series
will have that many episodes. I`m just tidying the program up and it
seemed wasteful to declare an array that large when it probably isn`t
needed. The only other way would be to read the xml file twice, firstly
counting the number of episodes and then declaring the array, and then
read it again and fetch in the episode data.

You should not need to read the episodes twice.

Once you load the XML document, use XPATH query statements to find
elements of the document. XPATH is specifically designed to search
for the "DOM" of the XML documentt to returns a list of elements by
providing it a query statement. In other words, if your XML file has
this:

<?xml version='1.0'?>
<shows>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<shows>

Than you can use an xpath like

"//shows/series"

to find all the <series> within the </shows> branch.

The XPATH language syntax is rich and the official specification for
XPATH is located here.

http://www.w3.org/TR/xpath

--
 
M

Mike

roidy said:
NoOfEpisodes is unknown until the episodes have read in one by one from
the xml file. In the previous version of the program I just gave the
array a large value eg. 40 as it is unlikely any season of a TV series
will have that many episodes. I`m just tidying the program up and it
seemed wasteful to declare an array that large when it probably isn`t
needed. The only other way would be to read the xml file twice, firstly
counting the number of episodes and then declaring the array, and then
read it again and fetch in the episode data.

You should not need to read the episodes twice.

Once you load the XML document, use XPATH query statements to find
elements of the document. XPATH is specifically designed to search
for the "DOM" of the XML documentt to returns a list of elements by
providing it a query statement. In other words, if your XML file has
this:

<?xml version='1.0'?>
<shows>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<shows>

Than you can use an xpath like

"//shows/series"

to find all the <series> within the </shows> branch.

The XPATH language syntax is rich and the official specification for
XPATH is located here.

http://www.w3.org/TR/xpath

--
 
T

Tom Shelton

You should not need to read the episodes twice.

Once you load the XML document, use XPATH query statements to find
elements of the document. XPATH is specifically designed to search
for the "DOM" of the XML documentt to returns a list of elements by
providing it a query statement. In other words, if your XML file has
this:

<?xml version='1.0'?>
<shows>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<shows>

Than you can use an xpath like

"//shows/series"

to find all the <series> within the </shows> branch.

The XPATH language syntax is rich and the official specification for
XPATH is located here.

http://www.w3.org/TR/xpath

You know, if you are going to take the stupendously stupid way of reading the
file in to memory all at once - instead of streaming it - you might as well
make your live simple and use linq (air code):

dim series = from node in document.descendants("series") select node

And even then, you can always write an extension method and stream the file in
using an XmlTextReader - since this is a readonly forward operation. Of
course, this is a much more complex operation in VB then in C#, because of the
lack of yield return.... But, still doable.
 
T

Tom Shelton

You should not need to read the episodes twice.

Once you load the XML document, use XPATH query statements to find
elements of the document. XPATH is specifically designed to search
for the "DOM" of the XML documentt to returns a list of elements by
providing it a query statement. In other words, if your XML file has
this:

<?xml version='1.0'?>
<shows>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<series>....</series>
<shows>

Than you can use an xpath like

"//shows/series"

to find all the <series> within the </shows> branch.

The XPATH language syntax is rich and the official specification for
XPATH is located here.

http://www.w3.org/TR/xpath

You know, if you are going to take the stupendously stupid way of reading the
file in to memory all at once - instead of streaming it - you might as well
make your live simple and use linq (air code):

dim series = from node in document.descendants("series") select node

And even then, you can always write an extension method and stream the file in
using an XmlTextReader - since this is a readonly forward operation. Of
course, this is a much more complex operation in VB then in C#, because of the
lack of yield return.... But, still doable.
 
M

Mike

Tom said:
You know, if you are going to take the stupendously stupid way of reading the
file in to memory all at once - instead of streaming it - you might as well
make your live simple and use linq (air code):

Where did I say XML/XPATH will read the entire document and not parse
it as it reads it in? I don't think I made any suggestion to the
contrary, nor that the .NET XML/XPATH class will not stream it in. In
fact, I'm sure the XML parser in .NET, if its like any other standard
XML parser, it will read it using buffered memory and its was not part
of the thinking process for the author, it is inherent to the Windows
RTL (unless the coder turns it off) and further mode, it might be
virtualized as a file map. Or it might has some smarts, look at the
size of the file and decide its it one shot read, streamed or mapped
- in increasing size order. That use to be a consideration in the
past, but today, Windows, unless you turn it off in you open file
commands (CreateFile()), everything is buffered I/O - virtualized. In
short, these concerns are lot less today and when the text files are
large (Whats large today?) there are standard ways to deal with them.
dim series = from node in document.descendants("series") select node

And even then, you can always write an extension method and stream the file in
using an XmlTextReader - since this is a readonly forward operation. Of
course, this is a much more complex operation in VB then in C#, because of the
lack of yield return.... But, still doable.

The fact of the matter is his direct straight forward solution based
on his problem statement is XML queries - A.K.A XPATH and if you think
LINQ will also work better, then he should look into it. I saw
references to LINQ but know nothing about it.

Anything is doable. But why reinvent the wheel? Use the tools that
already in .NET.

I currently use Pugxml in our product XML needs - a super fast, small
footprint XML/XPATH parser and it offers two modes to loading file
itself or user-defined. It gives you a buffer pointer to pass whatever
amount you wish to chunk in as it parsers the blocks.
 
M

Mike

Tom said:
You know, if you are going to take the stupendously stupid way of reading the
file in to memory all at once - instead of streaming it - you might as well
make your live simple and use linq (air code):

Where did I say XML/XPATH will read the entire document and not parse
it as it reads it in? I don't think I made any suggestion to the
contrary, nor that the .NET XML/XPATH class will not stream it in. In
fact, I'm sure the XML parser in .NET, if its like any other standard
XML parser, it will read it using buffered memory and its was not part
of the thinking process for the author, it is inherent to the Windows
RTL (unless the coder turns it off) and further mode, it might be
virtualized as a file map. Or it might has some smarts, look at the
size of the file and decide its it one shot read, streamed or mapped
- in increasing size order. That use to be a consideration in the
past, but today, Windows, unless you turn it off in you open file
commands (CreateFile()), everything is buffered I/O - virtualized. In
short, these concerns are lot less today and when the text files are
large (Whats large today?) there are standard ways to deal with them.
dim series = from node in document.descendants("series") select node

And even then, you can always write an extension method and stream the file in
using an XmlTextReader - since this is a readonly forward operation. Of
course, this is a much more complex operation in VB then in C#, because of the
lack of yield return.... But, still doable.

The fact of the matter is his direct straight forward solution based
on his problem statement is XML queries - A.K.A XPATH and if you think
LINQ will also work better, then he should look into it. I saw
references to LINQ but know nothing about it.

Anything is doable. But why reinvent the wheel? Use the tools that
already in .NET.

I currently use Pugxml in our product XML needs - a super fast, small
footprint XML/XPATH parser and it offers two modes to loading file
itself or user-defined. It gives you a buffer pointer to pass whatever
amount you wish to chunk in as it parsers the blocks.
 
T

Tom Shelton

Where did I say XML/XPATH will read the entire document and not parse
it as it reads it in? I don't think I made any suggestion to the
contrary, nor that the .NET XML/XPATH class will not stream it in. In
fact, I'm sure the XML parser in .NET, if its like any other standard
XML parser, it will read it using buffered memory and its was not part
of the thinking process for the author, it is inherent to the Windows
RTL (unless the coder turns it off) and further mode, it might be
virtualized as a file map. Or it might has some smarts, look at the
size of the file and decide its it one shot read, streamed or mapped
- in increasing size order. That use to be a consideration in the
past, but today, Windows, unless you turn it off in you open file
commands (CreateFile()), everything is buffered I/O - virtualized. In
short, these concerns are lot less today and when the text files are
large (Whats large today?) there are standard ways to deal with them.

I've not looked at the implementation of the .NET XPath classes - so, I can't
be sure how they are implemented. Though, there are basically two ways to
work with XML data, and that is DOM which loads the entire XML document model
into memory or using an XmlReader to stream the data. But, my comment had not
to do with that anyway. It was derived from comments made further up the
thread, where things like split and File.ReadAllLines were being discussed.

As for the size of files being less of a concern... That must be very domain
specific, because it's something I have to worry about quite often - so I take
it seriously when I see entire files slurped up in one fell swoop in
production code :) I've seen servers brought to their knees from this
seemingly simple method of reading data.

I'm not saying I never use stuff like File.ReadAllLines - but, I try to
carefully weigh the alternatives before I make this sort of decision.
The fact of the matter is his direct straight forward solution based
on his problem statement is XML queries - A.K.A XPATH and if you think
LINQ will also work better, then he should look into it. I saw
references to LINQ but know nothing about it.

You think that XPath syntax is more straight forward then the simple statement
above? I'm not saying don't learn XPath, because there are times you need it
even with LINQ - but, LINQ is definately easier and more straight forward.
Anything is doable. But why reinvent the wheel? Use the tools that
already in .NET.

LINQ is in .NET.
 
T

Tom Shelton

Where did I say XML/XPATH will read the entire document and not parse
it as it reads it in? I don't think I made any suggestion to the
contrary, nor that the .NET XML/XPATH class will not stream it in. In
fact, I'm sure the XML parser in .NET, if its like any other standard
XML parser, it will read it using buffered memory and its was not part
of the thinking process for the author, it is inherent to the Windows
RTL (unless the coder turns it off) and further mode, it might be
virtualized as a file map. Or it might has some smarts, look at the
size of the file and decide its it one shot read, streamed or mapped
- in increasing size order. That use to be a consideration in the
past, but today, Windows, unless you turn it off in you open file
commands (CreateFile()), everything is buffered I/O - virtualized. In
short, these concerns are lot less today and when the text files are
large (Whats large today?) there are standard ways to deal with them.

I've not looked at the implementation of the .NET XPath classes - so, I can't
be sure how they are implemented. Though, there are basically two ways to
work with XML data, and that is DOM which loads the entire XML document model
into memory or using an XmlReader to stream the data. But, my comment had not
to do with that anyway. It was derived from comments made further up the
thread, where things like split and File.ReadAllLines were being discussed.

As for the size of files being less of a concern... That must be very domain
specific, because it's something I have to worry about quite often - so I take
it seriously when I see entire files slurped up in one fell swoop in
production code :) I've seen servers brought to their knees from this
seemingly simple method of reading data.

I'm not saying I never use stuff like File.ReadAllLines - but, I try to
carefully weigh the alternatives before I make this sort of decision.
The fact of the matter is his direct straight forward solution based
on his problem statement is XML queries - A.K.A XPATH and if you think
LINQ will also work better, then he should look into it. I saw
references to LINQ but know nothing about it.

You think that XPath syntax is more straight forward then the simple statement
above? I'm not saying don't learn XPath, because there are times you need it
even with LINQ - but, LINQ is definately easier and more straight forward.
Anything is doable. But why reinvent the wheel? Use the tools that
already in .NET.

LINQ is in .NET.
 
M

Michael Williams

In the previous version of the program I just gave
the array a large value eg. 40 as it is unlikely any
season of a TV series will have that many episodes.
I`m just tidying the program up and it seemed wasteful to declare an array
that large . . .

That's a piffling amount of memory, almost nothing at all these days. If
you're worried about a few hundred bytes then you'd better get rid of all
that dotnet framework immediately because it is gobbling up huge amounts of
memory!

Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top