Discussion:
Eliminating Unnecessary Boxing and Unboxing overhead.
(too old to reply)
Pete Olcott
2017-07-03 17:47:30 UTC
Permalink
I am considering translating a C++ system into C#.

My C++ classes contain other C++ classes and some POD (plain old data) types.

In C# this would be reference types containing reference types and value types.

Before Generics the equivalent of a C++ std::vector was ArrayList.

From what I understand the use of ArrayList has some extra overhead if one is merely trying to create the equivalent of a std::vector<int> and the Generic List<T> eliminates this extra overhead.

Is there any boxing and unboxing overhead when accessing an element of List<int>?

Is there any boxing and unboxing overhead when accessing a value member of a reference type?

Is there any boxing and unboxing overhead when accessing a value member of a reference type contained in a List<T>?

Is there a way to eliminate this boxing and unboxing overhead?
--
(Γ ⊨ _FS A) ≡ (Γ ⊢ _FS A)
x***@gmail.com
2017-07-03 21:47:44 UTC
Permalink
Post by Pete Olcott
I am considering translating a C++ system into C#.
My C++ classes contain other C++ classes and some POD (plain old data) types.
In C# this would be reference types containing reference types and value types.
Before Generics the equivalent of a C++ std::vector was ArrayList.
From what I understand the use of ArrayList has some extra overhead if one is merely trying to create the equivalent of a std::vector<int> and the Generic List<T> eliminates this extra overhead.
Is there any boxing and unboxing overhead when accessing an element of List<int>?
Is there any boxing and unboxing overhead when accessing a value member of a reference type?
Is there any boxing and unboxing overhead when accessing a value member of a reference type contained in a List<T>?
Is there a way to eliminate this boxing and unboxing overhead?
--
(Γ ⊨ _FS A) ≡ (Γ ⊢ _FS A)
Pete,

The answer to all of the above is no: None of those operations incur boxing. The caveat being that this only applies as long as you access those fields/members directly, and not through an object or interface reference.

For example, the following incurs no boxing:

`var intList = new List<int>() { 1, 2, 3 };
`var myInt = intList[0];`

However, the following examples both incur boxing:

`IComparable<int> c = intList[0];`
`object o = intList[0];`

When written as obviously as above, it can seem trivial to avoid this case, but be warned about passing value types as interface/object parameters to function calls.

-----------------

Ben Bowen / @Xenoprimate
http://www.benbowen.blog
Pete Olcott
2017-07-03 22:25:14 UTC
Permalink
Post by x***@gmail.com
Post by Pete Olcott
I am considering translating a C++ system into C#.
My C++ classes contain other C++ classes and some POD (plain old data) types.
In C# this would be reference types containing reference types and value types.
Before Generics the equivalent of a C++ std::vector was ArrayList.
From what I understand the use of ArrayList has some extra overhead if one is merely trying to create the equivalent of a std::vector<int> and the Generic List<T> eliminates this extra overhead.
Is there any boxing and unboxing overhead when accessing an element of List<int>?
Is there any boxing and unboxing overhead when accessing a value member of a reference type?
Is there any boxing and unboxing overhead when accessing a value member of a reference type contained in a List<T>?
Is there a way to eliminate this boxing and unboxing overhead?
--
(Γ ⊨ _FS A) ≡ (Γ ⊢ _FS A)
Pete,
The answer to all of the above is no: None of those operations incur boxing. The caveat being that this only applies as long as you access those fields/members directly, and not through an object or interface reference.
What about a List<T> member function that returns Count (the number of items) ?
(In C++ the object pointed to be the reference could provide immediate and direct access to its value types by dereferencing a pointer to them).
Post by x***@gmail.com
`var intList = new List<int>() { 1, 2, 3 };
`var myInt = intList[0];`
`IComparable<int> c = intList[0];`
`object o = intList[0];`
When written as obviously as above, it can seem trivial to avoid this case, but be warned about passing value types as interface/object parameters to function calls.
So to avoid boxing / unboxing overhead it would seem I only need to write my C# code using the same style as my C++ code.

I can use local value types, I can pass value types as parameters, I can use value types contained within reference types.

I couldn't see why anyone would ever want to pass value types as interface/object parameters to function calls.

Is there ever a good reason to write code that requires boxing and unboxing, or do generics make this obsolete?
Post by x***@gmail.com
-----------------
http://www.benbowen.blog
--
(Γ ⊨ _FS A) ≡ (Γ ⊢ _FS A)
Arne Vajhøj
2017-07-04 02:48:33 UTC
Permalink
Post by Pete Olcott
I couldn't see why anyone would ever want to pass value types as
interface/object parameters to function calls.
Is there ever a good reason to write code that requires boxing and
unboxing, or do generics make this obsolete?
Sometime you want a method that can process both ref and value
types. Value types will then be boxed.

Arne
Arne Vajhøj
2017-07-04 02:51:20 UTC
Permalink
Post by Pete Olcott
I am considering translating a C++ system into C#.
My C++ classes contain other C++ classes and some POD (plain old data) types.
In C# this would be reference types containing reference types and value types.
Before Generics the equivalent of a C++ std::vector was ArrayList.
From what I understand the use of ArrayList has some extra overhead if
one is merely trying to create the equivalent of a std::vector<int> and
the Generic List<T> eliminates this extra overhead.
Yes.

That was fixed 12 years ago.
Post by Pete Olcott
Is there any boxing and unboxing overhead when accessing an element of List<int>?
Is there any boxing and unboxing overhead when accessing a value member
of a reference type?
Is there any boxing and unboxing overhead when accessing a value member
of a reference type contained in a List<T>?
Is there a way to eliminate this boxing and unboxing overhead?
What you listed does not have it.

But unless you are in the math/vector/matrix domain then I doubt
that boxing/unboxing will have any significant impact on overall
performance.

Arne
Pete Olcott
2017-07-04 03:45:10 UTC
Permalink
Post by Arne Vajhøj
Post by Pete Olcott
I am considering translating a C++ system into C#.
My C++ classes contain other C++ classes and some POD (plain old data) types.
In C# this would be reference types containing reference types and value types.
Before Generics the equivalent of a C++ std::vector was ArrayList.
From what I understand the use of ArrayList has some extra overhead if one is merely trying to create the equivalent of a std::vector<int> and the Generic List<T> eliminates this extra overhead.
Yes.
That was fixed 12 years ago.
Post by Pete Olcott
Is there any boxing and unboxing overhead when accessing an element of List<int>?
Is there any boxing and unboxing overhead when accessing a value member of a reference type?
Is there any boxing and unboxing overhead when accessing a value member of a reference type contained in a List<T>?
Is there a way to eliminate this boxing and unboxing overhead?
What you listed does not have it.
But unless you are in the math/vector/matrix domain then I doubt
that boxing/unboxing will have any significant impact on overall
performance.
Arne
My system may be on a single desktop machine with 1000 other concurrent systems operating from this same hardware.

I want to provide good response time with 1/1000 of this system's resources.

When I write C++ code I understand the under-the-covers stuff well enough to duplicate the performance of hand-coded assembly language.

I want to do the same with C#.
--
(Γ ⊨ _FS A) ≡ (Γ ⊢ _FS A)
Arne Vajhøj
2017-07-04 18:41:29 UTC
Permalink
Post by Pete Olcott
Post by Arne Vajhøj
But unless you are in the math/vector/matrix domain then I doubt
that boxing/unboxing will have any significant impact on overall
performance.
My system may be on a single desktop machine with 1000 other concurrent
systems operating from this same hardware.
I want to provide good response time with 1/1000 of this system's resources.
I am still not convinced that for most code boxing/unboxing is a
real problem.
Post by Pete Olcott
When I write C++ code I understand the under-the-covers stuff well
enough to duplicate the performance of hand-coded assembly language.
I want to do the same with C#.
I am skeptical about whether C# is the right language for that.

I will claim that the vast majority of C# is written after the
paradigm "write clear concise code and let the optimizer worry
about the optimization".

Arne
Pete Olcott
2017-07-04 21:17:34 UTC
Permalink
Post by Arne Vajhøj
Post by Pete Olcott
Post by Arne Vajhøj
But unless you are in the math/vector/matrix domain then I doubt
that boxing/unboxing will have any significant impact on overall
performance.
My system may be on a single desktop machine with 1000 other concurrent systems operating from this same hardware.
I want to provide good response time with 1/1000 of this system's resources.
I am still not convinced that for most code boxing/unboxing is a
real problem.
Depending on what is going on under-the-covers, it may be the case that boxing and boxing mostly ceased to exist ever since generics.
Post by Arne Vajhøj
Post by Pete Olcott
When I write C++ code I understand the under-the-covers stuff well enough to duplicate the performance of hand-coded assembly language.
I want to do the same with C#.
I am skeptical about whether C# is the right language for that.
I will claim that the vast majority of C# is written after the
paradigm "write clear concise code and let the optimizer worry
about the optimization".
Arne
Which may now be the case as the C# language and .NET has matured.
I am estimating that well-written C# code may be as efficient now as well written C++ code.
--
(Γ ⊨ _FS A) ≡ (Γ ⊢ _FS A)
Arne Vajhøj
2017-07-04 23:35:43 UTC
Permalink
Post by Pete Olcott
Post by Arne Vajhøj
Post by Pete Olcott
When I write C++ code I understand the under-the-covers stuff well
enough to duplicate the performance of hand-coded assembly language.
I want to do the same with C#.
I am skeptical about whether C# is the right language for that.
I will claim that the vast majority of C# is written after the
paradigm "write clear concise code and let the optimizer worry
about the optimization".
Which may now be the case as the C# language and .NET has matured.
I am estimating that well-written C# code may be as efficient now as well written C++ code.
It is the standard assumption that for most normal code the difference
between C# JIT and C++ AOT is rather small.

Arne
Pete Olcott
2017-07-05 02:10:34 UTC
Permalink
Post by Arne Vajhøj
Post by Pete Olcott
Post by Arne Vajhøj
Post by Pete Olcott
When I write C++ code I understand the under-the-covers stuff well enough to duplicate the performance of hand-coded assembly language.
I want to do the same with C#.
I am skeptical about whether C# is the right language for that.
I will claim that the vast majority of C# is written after the
paradigm "write clear concise code and let the optimizer worry
about the optimization".
Which may now be the case as the C# language and .NET has matured.
I am estimating that well-written C# code may be as efficient now as well written C++ code.
It is the standard assumption that for most normal code the difference
between C# JIT and C++ AOT is rather small.
Arne
Yet C# has passed Java (in machine efficiency) by quite a bit now.
--
(Γ ⊨ _FS A) ≡ (Γ ⊢ _FS A)
Arne Vajhøj
2017-07-06 01:51:00 UTC
Permalink
Post by Pete Olcott
Post by Arne Vajhøj
Post by Pete Olcott
Which may now be the case as the C# language and .NET has matured.
I am estimating that well-written C# code may be as efficient now as
well written C++ code.
It is the standard assumption that for most normal code the difference
between C# JIT and C++ AOT is rather small.
Yet C# has passed Java (in machine efficiency) by quite a bit now.
In general JVM JIT and CLR JIT seems very similar in optimization.

But your specific code will be much faster in C# than in Java,
because even with a generic list Java does use boxing and unboxing.

Arne

Loading...