473,788 Members | 2,854 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Array.Resize or List<> or some other data structure

Hello, Newsgroupians:

I've an optimization question for you all really quick. I have a stream
that I am reading some bytes. At times, the stream can contain a small
amount of bytes such as 50 or so or it can contain as much 10000000 bytes.
In reality, I do not know the maximum number of bytes.

In my function, I am going to read() the byte stream using a buffer. Now,
is it better to read it into a buffer and dump the buffer into a List<byte>
maybe using AddRange() or should I Array.Resize the buffer to grow a specific
size everytime?

Code for List<byte>

List<bytelstByt es = new List<byte>();
byte[] buffer = new byte[2048];

while (stream.Read(bu ffer, 0, buffer.Length) != -1)
{
lstBytes.AddRan ge(buffer);
}
return lstBytes.ToArra y();

Code for resizing array:

byte[] buffer = new byte[2048];
while (stream.Read(bu ffer, buffer.Length - 2048, 2048) != -1)
{
Array.Resize(re f buffer, buffer.Size + 2048);
}
return buffer;

So which way should I use? Should I dump it into a list everytime, or
should I resize the array everytime? Is there another way you would
recommend? Thank you all for your help and suggestions.
Trecius
Oct 17 '08 #1
9 6185
Are you aware there is:

byte [] bytes = File.ReadAllByt es("file.bin") ;

?

"Trecius" wrote:
Hello, Newsgroupians:

I've an optimization question for you all really quick. I have a stream
that I am reading some bytes. At times, the stream can contain a small
amount of bytes such as 50 or so or it can contain as much 10000000 bytes.
In reality, I do not know the maximum number of bytes.

In my function, I am going to read() the byte stream using a buffer. Now,
is it better to read it into a buffer and dump the buffer into a List<byte>
maybe using AddRange() or should I Array.Resize the buffer to grow a specific
size everytime?

Code for List<byte>

List<bytelstByt es = new List<byte>();
byte[] buffer = new byte[2048];

while (stream.Read(bu ffer, 0, buffer.Length) != -1)
{
lstBytes.AddRan ge(buffer);
}
return lstBytes.ToArra y();

Code for resizing array:

byte[] buffer = new byte[2048];
while (stream.Read(bu ffer, buffer.Length - 2048, 2048) != -1)
{
Array.Resize(re f buffer, buffer.Size + 2048);
}
return buffer;

So which way should I use? Should I dump it into a list everytime, or
should I resize the array everytime? Is there another way you would
recommend? Thank you all for your help and suggestions.
Trecius
Oct 17 '08 #2
My stream isn't a file. :(

"Family Tree Mike" wrote:
Are you aware there is:

byte [] bytes = File.ReadAllByt es("file.bin") ;

?

"Trecius" wrote:
Hello, Newsgroupians:

I've an optimization question for you all really quick. I have a stream
that I am reading some bytes. At times, the stream can contain a small
amount of bytes such as 50 or so or it can contain as much 10000000 bytes.
In reality, I do not know the maximum number of bytes.

In my function, I am going to read() the byte stream using a buffer. Now,
is it better to read it into a buffer and dump the buffer into a List<byte>
maybe using AddRange() or should I Array.Resize the buffer to grow a specific
size everytime?

Code for List<byte>

List<bytelstByt es = new List<byte>();
byte[] buffer = new byte[2048];

while (stream.Read(bu ffer, 0, buffer.Length) != -1)
{
lstBytes.AddRan ge(buffer);
}
return lstBytes.ToArra y();

Code for resizing array:

byte[] buffer = new byte[2048];
while (stream.Read(bu ffer, buffer.Length - 2048, 2048) != -1)
{
Array.Resize(re f buffer, buffer.Size + 2048);
}
return buffer;

So which way should I use? Should I dump it into a list everytime, or
should I resize the array everytime? Is there another way you would
recommend? Thank you all for your help and suggestions.
Trecius
Oct 17 '08 #3
Then will Stream.Length work to initially size the array?

"Trecius" wrote:
My stream isn't a file. :(

"Family Tree Mike" wrote:
Are you aware there is:

byte [] bytes = File.ReadAllByt es("file.bin") ;

?

"Trecius" wrote:
Hello, Newsgroupians:
>
I've an optimization question for you all really quick. I have a stream
that I am reading some bytes. At times, the stream can contain a small
amount of bytes such as 50 or so or it can contain as much 10000000 bytes.
In reality, I do not know the maximum number of bytes.
>
In my function, I am going to read() the byte stream using a buffer. Now,
is it better to read it into a buffer and dump the buffer into a List<byte>
maybe using AddRange() or should I Array.Resize the buffer to grow a specific
size everytime?
>
Code for List<byte>
>
List<bytelstByt es = new List<byte>();
byte[] buffer = new byte[2048];
>
while (stream.Read(bu ffer, 0, buffer.Length) != -1)
{
lstBytes.AddRan ge(buffer);
}
return lstBytes.ToArra y();
>
>
>
Code for resizing array:
>
byte[] buffer = new byte[2048];
while (stream.Read(bu ffer, buffer.Length - 2048, 2048) != -1)
{
Array.Resize(re f buffer, buffer.Size + 2048);
}
return buffer;
>
>
>
So which way should I use? Should I dump it into a list everytime, or
should I resize the array everytime? Is there another way you would
recommend? Thank you all for your help and suggestions.
>
>
Trecius
Oct 17 '08 #4
Family Tree Mike wrote:
Then will Stream.Length work to initially size the array?
If his stream reads bytes from, say, a port, I guess Length is not
known before all bytes are read.

--
Rudy Velthuis http://rvelthuis.de

"The study of non-linear physics is like the study of non-elephant
biology." -- Unknown
Oct 17 '08 #5
In fact, it is a port. :)

"Rudy Velthuis" wrote:
Family Tree Mike wrote:
Then will Stream.Length work to initially size the array?

If his stream reads bytes from, say, a port, I guess Length is not
known before all bytes are read.

--
Rudy Velthuis http://rvelthuis.de

"The study of non-linear physics is like the study of non-elephant
biology." -- Unknown
Oct 17 '08 #6
On Fri, 17 Oct 2008 11:20:05 -0700, Trecius
<Tr*****@discus sions.microsoft .comwrote:
In fact, it is a port. :)
If by "port", you mean a NetworkStream retrieved from a Socket instance,
then Rudy is correct...the Length property cannot be determined and in
fact will always throw a NotSupportedExc eption.
Oct 17 '08 #7
On Fri, 17 Oct 2008 08:48:13 -0700, Trecius
<Tr*****@discus sions.microsoft .comwrote:
[...]
So which way should I use? Should I dump it into a list everytime, or
should I resize the array everytime? Is there another way you would
recommend? Thank you all for your help and suggestions.
The two approaches you're asking about are basically equivalent. The
List<Tclass uses an array internally, and will do effectively the same
operation as Array.Resize(). The only real difference between the two is
that List<Talways doubles the size of the storage, so that you need to
resize fewer and fewer times as the data gets larger. Of course, you
could always use that strategy when using Array.Resize() as well, if that
was important.

Personally, I wouldn't use either. I would make every effort to try to
process the bytes as they are read, so that they never have to be all in
memory at once. That's the most ideal solution, as it avoids the whole
business of having to buffer an arbitrarily large amount of data
altogether.

If you can't process the bytes as they are read, but instead need to store
them all up first, I would use a MemoryStream, and write to the
MemoryStream as the bytes come in. Then when you're done, you can use the
MemoryStream.To Array() method to get the byte array representing the data.

I believe that MemoryStream uses the same double-and-copy algorithm as
List<T>, so if that wound up being a performance liability, I would switch
to allocating individual buffers and storing them in a List<byte[]>. That
is, rather than resizing a single byte[] over and over, just allocate a
new byte[] when you've run out of room in your current byte[], storing a
reference to each byte[] in the List<byte[]>.

One more alternative would be to have the i/o code use individual byte[]
instances only, and hand those off to a different thread that deals with
writing them to a MemoryStream. In terms of performance, this would
probably be somewhere in between using a List<byte[]to store individual
buffers and just always writing to a MemoryStream.

With this alternative, you could either use a double- or triple-buffering
scheme where you have two or three such buffers that are used in rotation,
or you could just allocate a new buffer as needed, letting the used ones
be garbage collected after they've been copied to the MemoryStream. The
former has the advantage of not causing a lot of repeated allocations and
collections, at the cost of complexity and the possibility of having the
i/o thread having to wait for a buffer to become available.

Personally, if you have to buffer all the data, I would start with writing
to a MemoryStream. It is by far the simplest approach, and may well
perform adequately for your needs. Only if I ran into some specific
performance issue would I then start exploring some of these other
options. They are reasonably straightforward to code, but would certainly
obfuscate the core purpose of the code and any complication of the code
should avoided unless absolutely necessary.

Pete
Oct 17 '08 #8
Peter Duniho wrote:
On Fri, 17 Oct 2008 11:20:05 -0700, Trecius
<Tr*****@discus sions.microsoft .comwrote:
In fact, it is a port. :)

If by "port", you mean a NetworkStream retrieved from a Socket
instance, then Rudy is correct...the Length property cannot be
determined and in fact will always throw a NotSupportedExc eption.
I actually meant a physical port, like an USB port with some kind of
lab device attached, but the kind of port you meant has the same
problems. You simply can't know the amount of data to expect.

After all, data can be read from so many sources. <g>

--
Rudy Velthuis http://rvelthuis.de

"1001 words say more than one picture" -- Chinese proverb
Oct 17 '08 #9
Thank you, Mr. Duniho. I will use your suggestion. It seems like it will
work perfectly for my needs. Thank you again.

Trecius

"Peter Duniho" wrote:
On Fri, 17 Oct 2008 08:48:13 -0700, Trecius
<Tr*****@discus sions.microsoft .comwrote:
[...]
So which way should I use? Should I dump it into a list everytime, or
should I resize the array everytime? Is there another way you would
recommend? Thank you all for your help and suggestions.

The two approaches you're asking about are basically equivalent. The
List<Tclass uses an array internally, and will do effectively the same
operation as Array.Resize(). The only real difference between the two is
that List<Talways doubles the size of the storage, so that you need to
resize fewer and fewer times as the data gets larger. Of course, you
could always use that strategy when using Array.Resize() as well, if that
was important.

Personally, I wouldn't use either. I would make every effort to try to
process the bytes as they are read, so that they never have to be all in
memory at once. That's the most ideal solution, as it avoids the whole
business of having to buffer an arbitrarily large amount of data
altogether.

If you can't process the bytes as they are read, but instead need to store
them all up first, I would use a MemoryStream, and write to the
MemoryStream as the bytes come in. Then when you're done, you can use the
MemoryStream.To Array() method to get the byte array representing the data.

I believe that MemoryStream uses the same double-and-copy algorithm as
List<T>, so if that wound up being a performance liability, I would switch
to allocating individual buffers and storing them in a List<byte[]>. That
is, rather than resizing a single byte[] over and over, just allocate a
new byte[] when you've run out of room in your current byte[], storing a
reference to each byte[] in the List<byte[]>.

One more alternative would be to have the i/o code use individual byte[]
instances only, and hand those off to a different thread that deals with
writing them to a MemoryStream. In terms of performance, this would
probably be somewhere in between using a List<byte[]to store individual
buffers and just always writing to a MemoryStream.

With this alternative, you could either use a double- or triple-buffering
scheme where you have two or three such buffers that are used in rotation,
or you could just allocate a new buffer as needed, letting the used ones
be garbage collected after they've been copied to the MemoryStream. The
former has the advantage of not causing a lot of repeated allocations and
collections, at the cost of complexity and the possibility of having the
i/o thread having to wait for a buffer to become available.

Personally, if you have to buffer all the data, I would start with writing
to a MemoryStream. It is by far the simplest approach, and may well
perform adequately for your needs. Only if I ran into some specific
performance issue would I then start exploring some of these other
options. They are reasonably straightforward to code, but would certainly
obfuscate the core purpose of the code and any complication of the code
should avoided unless absolutely necessary.

Pete
Oct 17 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
5633
by: Dave | last post by:
Hello all, After perusing the Standard, I believe it is true to say that once you insert an element into a std::list<>, its location in memory never changes. This makes a std::list<> ideal for storing vertices of an arbitrary n-ary tree where a vertex contain pointers to its parent / children. These parent / child vertices need to stay put if we've got pointers to them somewhere! Am I correct in my assertion?
8
1587
by: Francisco | last post by:
Hello, Is there any code faster than this array position manipulation (some code omitted for brevity)?: internal struct TreeNodeTableItem { public int a; public int b; public int c; public int d;
35
5895
by: Lee Crabtree | last post by:
This seems inconsistent and more than a little bizarre. Array.Clear sets all elements of the array to their default values (0, null, whatever), whereas List<>.Clear removes all items from the list. That part makes a reasonable amount of sense, as you can't actually take items away from an Array. However, there doesn't seem to be a way to perform the same operation in one fell swoop on a List<>. For example:
6
2988
by: Peter | last post by:
I have a WebService which returns a List of RunningReport class How do I read this XML data on the client side. How do I convert List<RunningReportfrom the WebService side to List<RunningReporton the client side I have tried the following: List<RunningReportreportList = null; localhost.ReportService localrs = new localhost.ReportService();
0
9498
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10364
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10172
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10110
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9967
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8993
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7517
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
1
4069
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3670
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.