473,320 Members | 2,080 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

ArrayList without Boxing and UnBoxing

How can I create an ArrayList in the older version of .NET that does not require
the expensive Boxing and UnBoxing operations?

In my case it will be an ArrayList of structures of ordinal types.

Thanks.
Nov 3 '06
94 5558
Peter Olcott wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
>You are looking at the combined store and retrive numbers.

The split up were:

save retrieve
integer array : 0,08 0,03
object array : 3,05 0,08
array list : 4,67 0,16
generic list : 0,31 0,05

Arne

I did not understand these numbers:
(1) Is the comma intended to take tha place of a decimal point, or are there
four different numbers per line ?
Comma is decimal point in the locale I am using.
(2) What are these numbers clocks per operation? Seconds per fixed number of
operations ?
The last. But it should really not matter. Only that smaller is better.
And that should be obvious from the results.
(3) How do they compare to std::vector ?
A posted 8-10 posts previous:

GCC 3.2 with -O3:

integer array 0.06 0.03
vector 0.33 0.06

BCB 5.6:

integer array 0.06 0.03
vector 0.33 0.05

VC++ 7.1 with /Ox:

integer array 0.06 0.03
vector 0.44 0.05

Arne
Nov 17 '06 #51
Peter Olcott wrote:
"Ben Newsam" <be********@ukonline.co.ukwrote in message
news:p3********************************@4ax.com...
>On Wed, 15 Nov 2006 21:45:39 -0500, Arne Vajhøj <ar**@vajhoej.dk>
wrote:
>>Ben Newsam wrote:
On Wed, 15 Nov 2006 19:27:38 -0600, "Peter Olcott"
<No****@SeeScreen.comwrote:
I am only learning the beginnings of C#, but even I recognize that it
is bound to be slower than C or C++. I am willing to allow that as
long as I get something back in return. I am still hopeful about that,
but the jury is still out...
Well - that is not obvious to me.

Why should optimization at compile time be better
than optimization first time run ?
Faster. I wouldn't know about better.

There are two factors: when you have the original source code more information
is provided so that a greater degree of changes can be made, and still derive
the same result. From a marketability point of view slow compile times effect
fewer users than slower run times, so you have more time to do a better job at
compile time. Neither of these two things is a limitation for .NET.
I think most optimizing compiler do convert source to an
intermediate form before optimizing anyway, so the source info
is lost when the optimization is done.

Arne
Nov 17 '06 #52

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
>"Ben Newsam" <be********@ukonline.co.ukwrote in message
news:p3********************************@4ax.com.. .
>>On Wed, 15 Nov 2006 21:45:39 -0500, Arne Vajhøj <ar**@vajhoej.dk>
wrote:
Ben Newsam wrote:
On Wed, 15 Nov 2006 19:27:38 -0600, "Peter Olcott"
<No****@SeeScreen.comwrote:
I am only learning the beginnings of C#, but even I recognize that it
is bound to be slower than C or C++. I am willing to allow that as
long as I get something back in return. I am still hopeful about that,
but the jury is still out...
Well - that is not obvious to me.

Why should optimization at compile time be better
than optimization first time run ?
Faster. I wouldn't know about better.

There are two factors: when you have the original source code more
information is provided so that a greater degree of changes can be made, and
still derive the same result. From a marketability point of view slow compile
times effect fewer users than slower run times, so you have more time to do a
better job at compile time. Neither of these two things is a limitation for
.NET.

I think most optimizing compiler do convert source to an
intermediate form before optimizing anyway, so the source info
is lost when the optimization is done.

Arne
The source code itself it lost, but, not the richer semantic structure that is
provided by the source.
Nov 17 '06 #53

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
>"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
>>You are looking at the combined store and retrive numbers.

The split up were:

save retrieve
integer array : 0,08 0,03
object array : 3,05 0,08
array list : 4,67 0,16
generic list : 0,31 0,05

Arne

I did not understand these numbers:
(1) Is the comma intended to take tha place of a decimal point, or are there
four different numbers per line ?

Comma is decimal point in the locale I am using.
>(2) What are these numbers clocks per operation? Seconds per fixed number of
operations ?

The last. But it should really not matter. Only that smaller is better.
And that should be obvious from the results.
>(3) How do they compare to std::vector ?

A posted 8-10 posts previous:

GCC 3.2 with -O3:

integer array 0.06 0.03
vector 0.33 0.06

BCB 5.6:

integer array 0.06 0.03
vector 0.33 0.05

VC++ 7.1 with /Ox:

integer array 0.06 0.03
vector 0.44 0.05

Arne
So then the answer is clear, .NET without generics can be unacceptably slow,
58-fold slower than unmanaged array storage and 500% slower than unmanaged array
retrieval, but, with generics very comparable to std::vector. I would suppose
that we could greatly speed up the std::vector storage by using resize(), and
operator[]() instead of push_back(). With my time critical processing, I know
the size in advance.
Nov 17 '06 #54
Peter Olcott wrote:
So then the answer is clear, .NET without generics can be unacceptably slow,
58-fold slower than unmanaged array storage and 500% slower than unmanaged array
retrieval, but, with generics very comparable to std::vector. I would suppose
that we could greatly speed up the std::vector storage by using resize(), and
operator[]() instead of push_back(). With my time critical processing, I know
the size in advance.
If you know the size then why not just allocate a good
oldfashioned array ?

Arne
Nov 18 '06 #55

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
>So then the answer is clear, .NET without generics can be unacceptably slow,
58-fold slower than unmanaged array storage and 500% slower than unmanaged
array retrieval, but, with generics very comparable to std::vector. I would
suppose that we could greatly speed up the std::vector storage by using
resize(), and operator[]() instead of push_back(). With my time critical
processing, I know the size in advance.

If you know the size then why not just allocate a good
oldfashioned array ?

Arne
I would estimate that might not be one of the .NET best practices. My purpose
here on this forum is to evaluate the feasibility of using .NET for my screen
recognition system. It looks likes your benchmarks derive a passing score for
..NET that includes generics, and a failing score for earlier versions. Thanks
for all your help.
Nov 18 '06 #56

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
>So then the answer is clear, .NET without generics can be unacceptably slow,
58-fold slower than unmanaged array storage and 500% slower than unmanaged
array retrieval, but, with generics very comparable to std::vector. I would
suppose that we could greatly speed up the std::vector storage by using
resize(), and operator[]() instead of push_back(). With my time critical
processing, I know the size in advance.

If you know the size then why not just allocate a good
oldfashioned array ?

Arne
Oh Yeah, one more question, an Array List can be allocated in advance, can't it?
Nov 18 '06 #57

Peter Olcott wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
So then the answer is clear, .NET without generics can be unacceptablyslow,
58-fold slower than unmanaged array storage and 500% slower than unmanaged
array retrieval, but, with generics very comparable to std::vector. I would
suppose that we could greatly speed up the std::vector storage by using
resize(), and operator[]() instead of push_back(). With my time critical
processing, I know the size in advance.
If you know the size then why not just allocate a good
oldfashioned array ?

Arne

I would estimate that might not be one of the .NET best practices.
Good grief.

Your original post stated that the solution had to work on "older
versions of .NET" and implied that you required a dynamic memory
structure. Now, after mountains of back-and-forth, it turns out that
you have no problem with using .NET 2.0 and that you know the size up
front.

If you'd told us those two things at the outset it would have saved a
lot of time and effort.

If you know the size up front, use an array. Period. Dynamic structures
cost: you get what you pay for, and you pay for what you get. This has
nothing to do with .NET as such: it's just a basic tenet of computing.
My purpose here on this forum is to evaluate the feasibility of using .NET for my screen
recognition system. It looks likes your benchmarks derive a passing scorefor
.NET that includes generics, and a failing score for earlier versions.
Only for dynamic memory structures. If you can use a fixed-size array
then any version of .NET will yield similar (and speedy) results. If
you require a dynamic structure then .NET 1.1 forces you to box and
unbox values (unless you roll your own, naturally). .NET 2.0 introduces
generics which get around the boxing issue.

But for heaven's sake, next time state the situation clearly, so that
it doesn't take 50 or so posts to arrive at a conclusion!

Nov 18 '06 #58
Peter Olcott wrote:
Oh Yeah, one more question, an Array List can be allocated in advance, can't it?
Both ArrayList and List<has a constructor with an int argument
specifying initial capacity.

Arne
Nov 18 '06 #59
I have to top post because somehow you managed to turn quoting off.
Can allocating an ordinary array, be done through the managed heap? If it can
not be done using the managed heap, then wouldn't allocating unmanaged memory be
considered a poor practice in terms of good .NET design?

There are two different facets to my problem, one requiring the array to
dynamically grow, and the other most time critical one, knows its size in
advance. Even the one that is required to dynamically grow, must do this
relatively quickly, thus can not take the boxing / unboxing overhead. I wanted
to see if I could adapt my system to .NET using my current compiler, the answer
is no. The next level question is can my system be adapted to .NET at all, the
answer is yes if I use generics.

"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@f16g2000cwb.googlegr oups.com...

Peter Olcott wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
So then the answer is clear, .NET without generics can be unacceptably
slow,
58-fold slower than unmanaged array storage and 500% slower than unmanaged
array retrieval, but, with generics very comparable to std::vector. I would
suppose that we could greatly speed up the std::vector storage by using
resize(), and operator[]() instead of push_back(). With my time critical
processing, I know the size in advance.
If you know the size then why not just allocate a good
oldfashioned array ?

Arne

I would estimate that might not be one of the .NET best practices.
Good grief.

Your original post stated that the solution had to work on "older
versions of .NET" and implied that you required a dynamic memory
structure. Now, after mountains of back-and-forth, it turns out that
you have no problem with using .NET 2.0 and that you know the size up
front.

If you'd told us those two things at the outset it would have saved a
lot of time and effort.

If you know the size up front, use an array. Period. Dynamic structures
cost: you get what you pay for, and you pay for what you get. This has
nothing to do with .NET as such: it's just a basic tenet of computing.
My purpose here on this forum is to evaluate the feasibility of using .NET for
my screen
recognition system. It looks likes your benchmarks derive a passing score for
.NET that includes generics, and a failing score for earlier versions.
Only for dynamic memory structures. If you can use a fixed-size array
then any version of .NET will yield similar (and speedy) results. If
you require a dynamic structure then .NET 1.1 forces you to box and
unbox values (unless you roll your own, naturally). .NET 2.0 introduces
generics which get around the boxing issue.

But for heaven's sake, next time state the situation clearly, so that
it doesn't take 50 or so posts to arrive at a conclusion!
Nov 18 '06 #60

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
>Oh Yeah, one more question, an Array List can be allocated in advance, can't
it?

Both ArrayList and List<has a constructor with an int argument
specifying initial capacity.

Arne
These can refer to any type of structure?
Which of these is closest to std::vector?
Nov 18 '06 #61
Peter Olcott wrote:
Can allocating an ordinary array, be done through the managed heap? If it can
not be done using the managed heap, then wouldn't allocating unmanaged memory be
considered a poor practice in terms of good .NET design?
Who said anything about unmanaged memory? I'm talking about using a
regular, boring managed array. Fixed-size arrays in .NET can be of any
type, including value types, and so required no boxing and unboxing in
order to store value types. There is no need to use unmanaged arrays.
There are two different facets to my problem, one requiring the array to
dynamically grow, and the other most time critical one, knows its size in
advance.
The use a dynamic structure for the first and a vanilla fixed-size
array for the second. Using a fixed-size array will certainly bring
speed benefits.
Even the one that is required to dynamically grow, must do this
relatively quickly, thus can not take the boxing / unboxing overhead. I wanted
to see if I could adapt my system to .NET using my current compiler, the answer
is no. The next level question is can my system be adapted to .NET at all, the
answer is yes if I use generics.
No, the answer is even better than that. The answer is that you can
achieve a high-speed dynamic structure in .NET 1.1, but you have to
program it yourself. Remember that ArrayList is just a wrapper around
an array that, when you attempt to add one element too many,
reallocates the array and copies the contents. You can write your own
ArrayList specific to your value type that will have no boxing /
unboxing overhead. The only thing that .NET 2.0 gives you is the
ability to use the dynamic data structures provided by the .NET
Framework without incurring boxing / unboxing overhead.

Nov 18 '06 #62

"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@e3g2000cwe.googlegro ups.com...
Peter Olcott wrote:
>Can allocating an ordinary array, be done through the managed heap? If it
can
not be done using the managed heap, then wouldn't allocating unmanaged memory
be
considered a poor practice in terms of good .NET design?

Who said anything about unmanaged memory? I'm talking about using a
regular, boring managed array. Fixed-size arrays in .NET can be of any
type, including value types, and so required no boxing and unboxing in
order to store value types. There is no need to use unmanaged arrays.
>There are two different facets to my problem, one requiring the array to
dynamically grow, and the other most time critical one, knows its size in
advance.

The use a dynamic structure for the first and a vanilla fixed-size
array for the second. Using a fixed-size array will certainly bring
speed benefits.
>Even the one that is required to dynamically grow, must do this
relatively quickly, thus can not take the boxing / unboxing overhead. I
wanted
to see if I could adapt my system to .NET using my current compiler, the
answer
is no. The next level question is can my system be adapted to .NET at all,
the
answer is yes if I use generics.

No, the answer is even better than that. The answer is that you can
achieve a high-speed dynamic structure in .NET 1.1, but you have to
program it yourself. Remember that ArrayList is just a wrapper around
an array that, when you attempt to add one element too many,
reallocates the array and copies the contents. You can write your own
ArrayList specific to your value type that will have no boxing /
unboxing overhead. The only thing that .NET 2.0 gives you is the
ability to use the dynamic data structures provided by the .NET
Framework without incurring boxing / unboxing overhead.
Actually it must be any array of struct of scalar types, 8-bit, 16-bit, and
32-bit integers, all unsigned.

struct MyType {
uint One;
ushort Two;
byte Three;
};

How do I go about creating the equivalent of a std::vector<MyTypethat does not
ever have boxing and unboxing overhead?
Nov 18 '06 #63
Peter Olcott wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
>Peter Olcott wrote:
>>Oh Yeah, one more question, an Array List can be allocated in advance, can't
it?
Both ArrayList and List<has a constructor with an int argument
specifying initial capacity.

These can refer to any type of structure?
Which of these is closest to std::vector?
ArrayList uses object meaning that it can take anything
but do boxing and unboxing.

List<uses whatever you use including struct (that is how
generics work).

Arne
Nov 18 '06 #64
Peter Olcott wrote:
Can allocating an ordinary array, be done through the managed heap? If it can
not be done using the managed heap, then wouldn't allocating unmanaged memory be
considered a poor practice in terms of good .NET design?
A normal array in C# is in managed heap.

And there are nothing wrong with using normal arrays in C#
if you know the size.

Arne
Nov 18 '06 #65
Peter Olcott wrote:
Actually it must be any array of struct of scalar types, 8-bit, 16-bit, and
32-bit integers, all unsigned.

struct MyType {
uint One;
ushort Two;
byte Three;
};

How do I go about creating the equivalent of a std::vector<MyTypethat does not
ever have boxing and unboxing overhead?
If you know the size:

MyType[] myarray = new MyType[noelm];

If you don't know the size and are on .NET 2.0:

List<MyTypemylist = new List<MyType>();

Arne
Nov 18 '06 #66

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
>Actually it must be any array of struct of scalar types, 8-bit, 16-bit, and
32-bit integers, all unsigned.

struct MyType {
uint One;
ushort Two;
byte Three;
};

How do I go about creating the equivalent of a std::vector<MyTypethat does
not ever have boxing and unboxing overhead?

If you know the size:

MyType[] myarray = new MyType[noelm];

If you don't know the size and are on .NET 2.0:

List<MyTypemylist = new List<MyType>();

Arne
Bruce said that this could be done using .NET 1.1
>you can achieve a high-speed dynamic structure in .NET 1.1, but you have to
program it yourself.

Nov 18 '06 #67
Peter Olcott wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
>If you know the size:

MyType[] myarray = new MyType[noelm];

If you don't know the size and are on .NET 2.0:

List<MyTypemylist = new List<MyType>();

Arne

Bruce said that this could be done using .NET 1.1
>you can achieve a high-speed dynamic structure in .NET 1.1, but you have to
program it yourself.
You can not make a fast generic one in 1.1, but you can make a fast
one specific for your type.

Arne
Nov 18 '06 #68

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
>"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk. ..
>>If you know the size:

MyType[] myarray = new MyType[noelm];

If you don't know the size and are on .NET 2.0:

List<MyTypemylist = new List<MyType>();

Arne

Bruce said that this could be done using .NET 1.1
>>you can achieve a high-speed dynamic structure in .NET 1.1, but you have to
program it yourself.

You can not make a fast generic one in 1.1, but you can make a fast
one specific for your type.

Arne
That is all that I need. How hard would this be? I already wrote a complete
std::vector from scratch, (for a C++ compiler lacking this capability) does it
require this same amount of programming?
Nov 18 '06 #69
Peter Olcott wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
>You can not make a fast generic one in 1.1, but you can make a fast
one specific for your type.

That is all that I need. How hard would this be? I already wrote a complete
std::vector from scratch, (for a C++ compiler lacking this capability) does it
require this same amount of programming?
Probably less.

If you only need a constructor + an Add method + an indexer
then it can not be many lines of code.

Arne
Nov 18 '06 #70

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
>"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
>>You can not make a fast generic one in 1.1, but you can make a fast
one specific for your type.

That is all that I need. How hard would this be? I already wrote a complete
std::vector from scratch, (for a C++ compiler lacking this capability) does
it require this same amount of programming?

Probably less.

If you only need a constructor + an Add method + an indexer
then it can not be many lines of code.

Arne
It also must dynamically re-allocate when it needs to grow in size.
Nov 19 '06 #71
Peter Olcott wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
>Peter Olcott wrote:
>>"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
You can not make a fast generic one in 1.1, but you can make a fast
one specific for your type.
That is all that I need. How hard would this be? I already wrote a complete
std::vector from scratch, (for a C++ compiler lacking this capability) does
it require this same amount of programming?
Probably less.

If you only need a constructor + an Add method + an indexer
then it can not be many lines of code.
It also must dynamically re-allocate when it needs to grow in size.
Yes - but that is inside the Add method.

Arne
Nov 19 '06 #72
Just to be clear, I believe std::vector is finally available in C++/CLI.

Regards,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***
Nov 19 '06 #73

Peter Olcott wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
You can not make a fast generic one in 1.1, but you can make a fast
one specific for your type.

That is all that I need. How hard would this be? I already wrote a complete
std::vector from scratch, (for a C++ compiler lacking this capability)does
it require this same amount of programming?
Probably less.

If you only need a constructor + an Add method + an indexer
then it can not be many lines of code.

Arne
It also must dynamically re-allocate when it needs to grow in size.
I do not vouch for the following: I wrote it off the top of my head, so
the syntax may not even be 100%, but to give you an idea:

public class MyValueTypeVector
{
private MyValueType[] _vector;
private int _upperBound;

public MyValudTypeVector() : this(10) { }

public MyValueTypeVector(int initialCapacity)
{
this._vector = new MyValueType[initialCapacity];
this._upperBound = 0;
}

public MyValueType this[int index]
{
get { return this._vector[index]; }
set { this._vector[index] = value; }
}

public int Length { get { return this._upperBound; } }

public void Add(MyValueType newMember)
{
if (this._upperBound >= this._vector.Length - 1)
{
MyValueType newVector[] = new
MyValueType[this._vector.Length * 2];
for (int i = 0; i < this._vector.Length; i++)
{
newVector[i] = this._vector[i];
}
this._vector = newVector;
}
this._vector[this._upperBound] = newMember;
this._upperBound += 1;
}
}

Some notes:

1. Notice that the indexer does no bounds check. That is, it is
possible for client code to read/write "past the end of" the array"
(above the upperBounds limit) so long as it doesn't write outside the
physical capacity of the allocated array. This is for speed. Adding the
check will cost one additional comparison per reference / assignment,
and would look like this:

public MyValueType this[int index]
{
get
{
if (index >= this._upperBounds) { throw new
IndexOutOfBoundsException(...); }
return this._vector[index];
}
set
{
if (index >= this._upperBounds) { throw new
IndexOutOfBoundsException(...); }
this._vector[index] = value;
}
}

Even this omits the index < 0 check, as this will throw an exception on
the array access itself. Again, not the prettiest, but we're going for
speed, here.

2. The original indexer is sufficiently simple that the compiler /
JITter should in-line the calls, reducing indexed access to the
"vector" to a simple array access (one bounds comparison, one address
calculation, and one read or write) with no method call overhead. If it
turns out tha the JITter does not in-line calls, you could always make
_vector public and access it directly via myVector.Vector[i], which is
ugly but possible. You shouldn't have to do this, though, because the
compiler really should in-line such a simple indexer as the first one.
The second with the bounds check probably wouldn't be in-lined.

3. The class is _not_ thread-safe. In particular, the reallocation
operation is _not_ atomic and cannot be made atomic without slowing the
whole thing down tremendously by introducing locks around the indexer
getter and setter and the Add operation including reallocation. I
assume that you're not multi-threading.

Nov 19 '06 #74
It looks like you have found the best possible solution to every aspect of my
original question. I am assuming that generics are equivalent to C++ templates
so that this solution could be adapted to become a generic solution. I am
assuming by what you said that C# does not have the equivalent the [inline]
keyword.

"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@h48g2000cwc.googlegr oups.com...

Peter Olcott wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
You can not make a fast generic one in 1.1, but you can make a fast
one specific for your type.

That is all that I need. How hard would this be? I already wrote a complete
std::vector from scratch, (for a C++ compiler lacking this capability) does
it require this same amount of programming?
Probably less.

If you only need a constructor + an Add method + an indexer
then it can not be many lines of code.

Arne
It also must dynamically re-allocate when it needs to grow in size.
I do not vouch for the following: I wrote it off the top of my head, so
the syntax may not even be 100%, but to give you an idea:

public class MyValueTypeVector
{
private MyValueType[] _vector;
private int _upperBound;

public MyValudTypeVector() : this(10) { }

public MyValueTypeVector(int initialCapacity)
{
this._vector = new MyValueType[initialCapacity];
this._upperBound = 0;
}

public MyValueType this[int index]
{
get { return this._vector[index]; }
set { this._vector[index] = value; }
}

public int Length { get { return this._upperBound; } }

public void Add(MyValueType newMember)
{
if (this._upperBound >= this._vector.Length - 1)
{
MyValueType newVector[] = new
MyValueType[this._vector.Length * 2];
for (int i = 0; i < this._vector.Length; i++)
{
newVector[i] = this._vector[i];
}
this._vector = newVector;
}
this._vector[this._upperBound] = newMember;
this._upperBound += 1;
}
}

Some notes:

1. Notice that the indexer does no bounds check. That is, it is
possible for client code to read/write "past the end of" the array"
(above the upperBounds limit) so long as it doesn't write outside the
physical capacity of the allocated array. This is for speed. Adding the
check will cost one additional comparison per reference / assignment,
and would look like this:

public MyValueType this[int index]
{
get
{
if (index >= this._upperBounds) { throw new
IndexOutOfBoundsException(...); }
return this._vector[index];
}
set
{
if (index >= this._upperBounds) { throw new
IndexOutOfBoundsException(...); }
this._vector[index] = value;
}
}

Even this omits the index < 0 check, as this will throw an exception on
the array access itself. Again, not the prettiest, but we're going for
speed, here.

2. The original indexer is sufficiently simple that the compiler /
JITter should in-line the calls, reducing indexed access to the
"vector" to a simple array access (one bounds comparison, one address
calculation, and one read or write) with no method call overhead. If it
turns out tha the JITter does not in-line calls, you could always make
_vector public and access it directly via myVector.Vector[i], which is
ugly but possible. You shouldn't have to do this, though, because the
compiler really should in-line such a simple indexer as the first one.
The second with the bounds check probably wouldn't be in-lined.

3. The class is _not_ thread-safe. In particular, the reallocation
operation is _not_ atomic and cannot be made atomic without slowing the
whole thing down tremendously by introducing locks around the indexer
getter and setter and the Add operation including reallocation. I
assume that you're not multi-threading.
Nov 19 '06 #75
public MyValueType this[uint index] // does this eliminate the possibility of
index < 0 ?
{
get { return this._vector[index]; }
set { this._vector[index] = value; }
}

"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@h48g2000cwc.googlegr oups.com...

Peter Olcott wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
You can not make a fast generic one in 1.1, but you can make a fast
one specific for your type.

That is all that I need. How hard would this be? I already wrote a complete
std::vector from scratch, (for a C++ compiler lacking this capability) does
it require this same amount of programming?
Probably less.

If you only need a constructor + an Add method + an indexer
then it can not be many lines of code.

Arne
It also must dynamically re-allocate when it needs to grow in size.
I do not vouch for the following: I wrote it off the top of my head, so
the syntax may not even be 100%, but to give you an idea:

public class MyValueTypeVector
{
private MyValueType[] _vector;
private int _upperBound;

public MyValudTypeVector() : this(10) { }

public MyValueTypeVector(int initialCapacity)
{
this._vector = new MyValueType[initialCapacity];
this._upperBound = 0;
}

public MyValueType this[int index]
{
get { return this._vector[index]; }
set { this._vector[index] = value; }
}

public int Length { get { return this._upperBound; } }

public void Add(MyValueType newMember)
{
if (this._upperBound >= this._vector.Length - 1)
{
MyValueType newVector[] = new
MyValueType[this._vector.Length * 2];
for (int i = 0; i < this._vector.Length; i++)
{
newVector[i] = this._vector[i];
}
this._vector = newVector;
}
this._vector[this._upperBound] = newMember;
this._upperBound += 1;
}
}

Some notes:

1. Notice that the indexer does no bounds check. That is, it is
possible for client code to read/write "past the end of" the array"
(above the upperBounds limit) so long as it doesn't write outside the
physical capacity of the allocated array. This is for speed. Adding the
check will cost one additional comparison per reference / assignment,
and would look like this:

public MyValueType this[int index]
{
get
{
if (index >= this._upperBounds) { throw new
IndexOutOfBoundsException(...); }
return this._vector[index];
}
set
{
if (index >= this._upperBounds) { throw new
IndexOutOfBoundsException(...); }
this._vector[index] = value;
}
}

Even this omits the index < 0 check, as this will throw an exception on
the array access itself. Again, not the prettiest, but we're going for
speed, here.

2. The original indexer is sufficiently simple that the compiler /
JITter should in-line the calls, reducing indexed access to the
"vector" to a simple array access (one bounds comparison, one address
calculation, and one read or write) with no method call overhead. If it
turns out tha the JITter does not in-line calls, you could always make
_vector public and access it directly via myVector.Vector[i], which is
ugly but possible. You shouldn't have to do this, though, because the
compiler really should in-line such a simple indexer as the first one.
The second with the bounds check probably wouldn't be in-lined.

3. The class is _not_ thread-safe. In particular, the reallocation
operation is _not_ atomic and cannot be made atomic without slowing the
whole thing down tremendously by introducing locks around the indexer
getter and setter and the Add operation including reallocation. I
assume that you're not multi-threading.
Nov 19 '06 #76

Peter Olcott wrote:
public MyValueType this[uint index] // does this eliminate the possibility of
index < 0 ?
{
get { return this._vector[index]; }
set { this._vector[index] = value; }
}
Yes, but you will have to mark the method as non-CLS compliant because
some .NET languages don't support unsigned types. No biggie unless
you're planning on calling the code from another .NET language.

And no, C# has no "inline" indication. That is left entirely up to the
compiler and the JITter.

Yes, C# generics offer similar functionality to C++ templates, although
the former are compiler constructs while the latter are
text-substitution constructs, which introduces some subtle differences.
Nonetheless, you can think of them as the "same thing" for basic usage
purposes.

Nov 19 '06 #77

"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@b28g2000cwb.googlegr oups.com...
>
Peter Olcott wrote:
>public MyValueType this[uint index] // does this eliminate the possibility
of
index < 0 ?
{
get { return this._vector[index]; }
set { this._vector[index] = value; }
}

Yes, but you will have to mark the method as non-CLS compliant because
some .NET languages don't support unsigned types. No biggie unless
you're planning on calling the code from another .NET language.

And no, C# has no "inline" indication. That is left entirely up to the
compiler and the JITter.

Yes, C# generics offer similar functionality to C++ templates, although
the former are compiler constructs while the latter are
text-substitution constructs, which introduces some subtle differences.
Nonetheless, you can think of them as the "same thing" for basic usage
purposes.
Now all that remains is to see if your get/set code mentioned above is placed
inline.
Nov 19 '06 #78

Peter Olcott wrote:
"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@b28g2000cwb.googlegr oups.com...

Peter Olcott wrote:
public MyValueType this[uint index] // does this eliminate the possibility
of
index < 0 ?
{
get { return this._vector[index]; }
set { this._vector[index] = value; }
}
Yes, but you will have to mark the method as non-CLS compliant because
some .NET languages don't support unsigned types. No biggie unless
you're planning on calling the code from another .NET language.

And no, C# has no "inline" indication. That is left entirely up to the
compiler and the JITter.

Yes, C# generics offer similar functionality to C++ templates, although
the former are compiler constructs while the latter are
text-substitution constructs, which introduces some subtle differences.
Nonetheless, you can think of them as the "same thing" for basic usage
purposes.

Now all that remains is to see if your get/set code mentioned above is placed
inline.
I know that the compiler inlines getters and setters that do nothing
but fetch and assign a corresponding field. I don't see why an indexer
would be any different.

Nov 20 '06 #79

"Bruce Wood" <br*******@canada.comwrote in message
news:11********************@b28g2000cwb.googlegrou ps.com...
>
Peter Olcott wrote:
>"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@b28g2000cwb.googleg roups.com...
>
Peter Olcott wrote:
public MyValueType this[uint index] // does this eliminate the
possibility
of
index < 0 ?
{
get { return this._vector[index]; }
set { this._vector[index] = value; }
}

Yes, but you will have to mark the method as non-CLS compliant because
some .NET languages don't support unsigned types. No biggie unless
you're planning on calling the code from another .NET language.

And no, C# has no "inline" indication. That is left entirely up to the
compiler and the JITter.

Yes, C# generics offer similar functionality to C++ templates, although
the former are compiler constructs while the latter are
text-substitution constructs, which introduces some subtle differences.
Nonetheless, you can think of them as the "same thing" for basic usage
purposes.

Now all that remains is to see if your get/set code mentioned above is placed
inline.

I know that the compiler inlines getters and setters that do nothing
but fetch and assign a corresponding field. I don't see why an indexer
would be any different.
Yes, but, this issue will remain unresolved until I know for sure. One of the
rules that I strictly enforce is never make any assumptions. How could the
answer to this question be empirically verified?
Nov 20 '06 #80
Peter Olcott <No****@SeeScreen.comwrote:
I know that the compiler inlines getters and setters that do nothing
but fetch and assign a corresponding field. I don't see why an indexer
would be any different.

Yes, but, this issue will remain unresolved until I know for sure. One of the
rules that I strictly enforce is never make any assumptions. How could the
answer to this question be empirically verified?
Compile a simple test app, run it under cordbg, and look at the
assembly generated.

You'll need to turn optimisations on everywhere though.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 20 '06 #81

"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP************************@msnews.microsoft.c om...
Peter Olcott <No****@SeeScreen.comwrote:
I know that the compiler inlines getters and setters that do nothing
but fetch and assign a corresponding field. I don't see why an indexer
would be any different.

Yes, but, this issue will remain unresolved until I know for sure. One of the
rules that I strictly enforce is never make any assumptions. How could the
answer to this question be empirically verified?

Compile a simple test app, run it under cordbg, and look at the
assembly generated.
Is it possible to look at the actual Intel specific assembly language?
>
You'll need to turn optimisations on everywhere though.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Nov 20 '06 #82
Peter Olcott <No****@SeeScreen.comwrote:
Compile a simple test app, run it under cordbg, and look at the
assembly generated.

Is it possible to look at the actual Intel specific assembly language?
Absolutely. It's not the easiest tool to get the hang of, but it's not
too bad after a bit of playing.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 20 '06 #83
Jeff Louie wrote:
Just to be clear, I believe std::vector is finally available in C++/CLI.
When has it not been ?

It seems to work (for a very simple example) in both
7.1/2003 and 8.0/2005.

Arne
Nov 23 '06 #84
Arne... Managed STL aka STL.NET was a delayed release after the RTM of
Visual
Studio 2005.

http://msdn2.microsoft.com/en-us/lib...00(vs.80).aspx

Regards,
Jeff
Jeff Louie wrote:
Just to be clear, I believe std::vector is finally available in
C++/CLI.

When has it not been ?

It seems to work (for a very simple example) in both
7.1/2003 and 8.0/2005.

*** Sent via Developersdex http://www.developersdex.com ***
Nov 24 '06 #85
"Jeff Louie" <an*******@devdex.comwrote in message
news:OL**************@TK2MSFTNGP03.phx.gbl...
Arne... Managed STL aka STL.NET was a delayed release after the RTM of
Visual
Studio 2005.

http://msdn2.microsoft.com/en-us/lib...00(vs.80).aspx
But, std::vector is a STL container, not a managed STL (now officially named STL/CLR)
container, and these were available since VC6.
Note that STL/CLR is now scheduled for ORCAS.

Willy.
Nov 24 '06 #86

"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
"Jeff Louie" <an*******@devdex.comwrote in message
news:OL**************@TK2MSFTNGP03.phx.gbl...
>Arne... Managed STL aka STL.NET was a delayed release after the RTM of
Visual
Studio 2005.

http://msdn2.microsoft.com/en-us/lib...00(vs.80).aspx

But, std::vector is a STL container, not a managed STL (now officially named
STL/CLR) container, and these were available since VC6.
Note that STL/CLR is now scheduled for ORCAS.
It is scheduled for killer whales?
>
Willy.


Nov 24 '06 #87
I would suppose that managed STL is not directly available from C#, and only
available from C++, right?

"Jeff Louie" <an*******@devdex.comwrote in message
news:OL**************@TK2MSFTNGP03.phx.gbl...
Arne... Managed STL aka STL.NET was a delayed release after the RTM of
Visual
Studio 2005.

http://msdn2.microsoft.com/en-us/lib...00(vs.80).aspx

Regards,
Jeff
Jeff Louie wrote:
>Just to be clear, I believe std::vector is finally available in
C++/CLI.

When has it not been ?

It seems to work (for a very simple example) in both
7.1/2003 and 8.0/2005.

*** Sent via Developersdex http://www.developersdex.com ***

Nov 24 '06 #88
"Peter Olcott" <No****@SeeScreen.comwrote in message
news:kl*******************@newsfe18.lga...
>I would suppose that managed STL is not directly available from C#, and only available from
C++, right?
The primary target is C++/CLI, but the STL/CLR containers can be operated on from any
managed language, like this:.

public ref class DataEngine {
public: ...
System::Collections::Generic::ICollection<int>^ GetDataContainer()
{
return m_data;
}
private:
cliext::vector<int>^ m_data; // a STL/CLR vector
};

//C# consumer
...
m_DataEng = new DataEngine();
ICollection<intiColl = m_DataEng.GetDataContainer();
foreach (Object objCur in iColl)
{ ... }

Willy.

Nov 24 '06 #89

Peter Olcott wrote:
It looks like you have found the best possible solution to every aspect of my
original question. I am assuming that generics are equivalent to C++ templates
so that this solution could be adapted to become a generic solution. I am
assuming by what you said that C# does not have the equivalent the [inline]
keyword.
After all of this back-and-forth about array access speed....

You DO realize that C# is a garbage-collected language, like Java, and
that at any time the GC can decide to kick in and do garbage
collection?

I know that people DO use C# for real-time applications, so you may
want to read up on how they ensure that particular paths through the
code (which are the paths with real-time deadlines to meet) aren't
interrupted by the GC.

Nov 24 '06 #90

"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@j44g2000cwa.googlegr oups.com...
>
Peter Olcott wrote:
>It looks like you have found the best possible solution to every aspect of my
original question. I am assuming that generics are equivalent to C++
templates
so that this solution could be adapted to become a generic solution. I am
assuming by what you said that C# does not have the equivalent the [inline]
keyword.

After all of this back-and-forth about array access speed....

You DO realize that C# is a garbage-collected language, like Java, and
that at any time the GC can decide to kick in and do garbage
collection?

I know that people DO use C# for real-time applications, so you may
want to read up on how they ensure that particular paths through the
code (which are the paths with real-time deadlines to meet) aren't
interrupted by the GC.
I would think that this might be something like forcing GC before you enter the
time critical path? I don't think that GC will be a problem for my most time
critical operation. For this operation I know the required size in advance for
the operation requiring the largest amount of memory, and the other operations
need so little memory that I could allocate the maximum required of this memory
in advance too, if I have to.

I will implement the original solution in unmanaged C++. Because of all of the
help that I have received here it looks like I will be able to transform this
original solution into a .NET implementation. In other words the .NET
architecture has passed the required feasibility tests. It looks like .NET can
provide the required performance, one way or another.

Also I just went back and reviewed, the help that you provided was apparently
the most useful of all help that was provided, thanks again.
Nov 24 '06 #91
Willy... I must very dense. I thought the OP was trying to write in
managed code
using patterns that he was familiar with such as the STL. I was trying
to point
out that his knowledge base in STL is still valuable and that this
knowledge can
be utilized in writing managed code if uses managed STL.

Regards,
Jeff
>But, std::vector is a STL container, not a managed STL (now officially
named
STL/CLR) container, and these were available since VC6.<

*** Sent via Developersdex http://www.developersdex.com ***
Nov 24 '06 #92

"Jeff Louie" <an*******@devdex.comwrote in message
news:ur**************@TK2MSFTNGP03.phx.gbl...
Willy... I must very dense. I thought the OP was trying to write in
managed code
using patterns that he was familiar with such as the STL. I was trying
to point
out that his knowledge base in STL is still valuable and that this
knowledge can
be utilized in writing managed code if uses managed STL.
That info was very useful too, thanks. I might do it that way with STL.
>
Regards,
Jeff
>>But, std::vector is a STL container, not a managed STL (now officially
named
STL/CLR) container, and these were available since VC6.<

*** Sent via Developersdex http://www.developersdex.com ***

Nov 24 '06 #93
"Jeff Louie" <an*******@devdex.comwrote in message
news:ur**************@TK2MSFTNGP03.phx.gbl...
Willy... I must very dense. I thought the OP was trying to write in
managed code
using patterns that he was familiar with such as the STL. I was trying
to point
out that his knowledge base in STL is still valuable and that this
knowledge can
be utilized in writing managed code if uses managed STL.

Regards,
Jeff
>>But, std::vector is a STL container, not a managed STL (now officially
named
STL/CLR) container, and these were available since VC6.<

*** Sent via Developersdex http://www.developersdex.com ***
Jeff,
I don't see a reason to be dense, in your reply to Arne:
Just to be clear, I believe std::vector is finally available in
C++/CLI.

I noticed the "finally", and that's why I said that std:vector is a native STL container,
which is available in all versions of VC++ since VC6. Don't know why you did use *finally*
here, really.

Willy.

Nov 24 '06 #94
Huh. OK. You are right. I am wrong.

Regards,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***
Nov 24 '06 #95

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

Similar topics

5
by: Kevin | last post by:
Hi All Can someone please tell me the difference between an Array and an ArrayList, and where I would be likely to use one over the other Thanks alot for any help
18
by: Sam | last post by:
Hi All I'm planing to write an application which allows users dynamically add their points (say you can add upto 30,000) and then draw xy graph. Should I use an array for my coordinate point...
48
by: Alex Chudnovsky | last post by:
I have come across with what appears to be a significant performance bug in ..NET 2.0 ArrayList.Sort method when compared with Array.Sort on the same data. Same data on the same CPU gets sorted a...
19
by: ahjiang | last post by:
hi there,, what is the real advantage of boxing and unboxing operations in csharp? tried looking ard the internet but couldnt find any articles on it. appreciate any help
161
by: Peter Olcott | last post by:
According to Troelsen in "C# and the .NET Platform" "Boxing can be formally defined as the process of explicitly converting a value type into a corresponding reference type." I think that my...
12
by: Justin | last post by:
Ok, I give up. I can't seem to construct a decent (productive) way of sorting my arraylist. I have a structure of two elements: Structure TabStructure Dim TabName As String Dim FullFilePath...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...

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.