List.RemoveAll() efficiency / compiler optimisation
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
Regarding efficiency, does anyone know if the compiler is clever enough to not create the array containing 1, 3, 5
for each iteration of the loop in the following code?
var foo = new List<int> { 1, 2, 3, 4, 5 };
foo.RemoveAll(i => new { 1, 3, 5 }.Contains(i));
I prefer it for readability, but not at the sake of performance.
c# arrays list linq compiler-optimization
add a comment |
Regarding efficiency, does anyone know if the compiler is clever enough to not create the array containing 1, 3, 5
for each iteration of the loop in the following code?
var foo = new List<int> { 1, 2, 3, 4, 5 };
foo.RemoveAll(i => new { 1, 3, 5 }.Contains(i));
I prefer it for readability, but not at the sake of performance.
c# arrays list linq compiler-optimization
25
try for your self sharplab.io
– Michael Randall
2 days ago
1
@MichaelRandall Great site. You should write an answer for this with an short example. This is interesseting for everybody, i think.
– kara
2 days ago
1
I'm really surprised but it looks like it does actually create a new instance of the 3 item array for each iteration inside the methodinternal bool <M>b__0_0(int i)
.
– maxp
2 days ago
add a comment |
Regarding efficiency, does anyone know if the compiler is clever enough to not create the array containing 1, 3, 5
for each iteration of the loop in the following code?
var foo = new List<int> { 1, 2, 3, 4, 5 };
foo.RemoveAll(i => new { 1, 3, 5 }.Contains(i));
I prefer it for readability, but not at the sake of performance.
c# arrays list linq compiler-optimization
Regarding efficiency, does anyone know if the compiler is clever enough to not create the array containing 1, 3, 5
for each iteration of the loop in the following code?
var foo = new List<int> { 1, 2, 3, 4, 5 };
foo.RemoveAll(i => new { 1, 3, 5 }.Contains(i));
I prefer it for readability, but not at the sake of performance.
c# arrays list linq compiler-optimization
c# arrays list linq compiler-optimization
edited 2 days ago
Michael Randall
37.2k84171
37.2k84171
asked 2 days ago
maxpmaxp
9,92735105175
9,92735105175
25
try for your self sharplab.io
– Michael Randall
2 days ago
1
@MichaelRandall Great site. You should write an answer for this with an short example. This is interesseting for everybody, i think.
– kara
2 days ago
1
I'm really surprised but it looks like it does actually create a new instance of the 3 item array for each iteration inside the methodinternal bool <M>b__0_0(int i)
.
– maxp
2 days ago
add a comment |
25
try for your self sharplab.io
– Michael Randall
2 days ago
1
@MichaelRandall Great site. You should write an answer for this with an short example. This is interesseting for everybody, i think.
– kara
2 days ago
1
I'm really surprised but it looks like it does actually create a new instance of the 3 item array for each iteration inside the methodinternal bool <M>b__0_0(int i)
.
– maxp
2 days ago
25
25
try for your self sharplab.io
– Michael Randall
2 days ago
try for your self sharplab.io
– Michael Randall
2 days ago
1
1
@MichaelRandall Great site. You should write an answer for this with an short example. This is interesseting for everybody, i think.
– kara
2 days ago
@MichaelRandall Great site. You should write an answer for this with an short example. This is interesseting for everybody, i think.
– kara
2 days ago
1
1
I'm really surprised but it looks like it does actually create a new instance of the 3 item array for each iteration inside the method
internal bool <M>b__0_0(int i)
.– maxp
2 days ago
I'm really surprised but it looks like it does actually create a new instance of the 3 item array for each iteration inside the method
internal bool <M>b__0_0(int i)
.– maxp
2 days ago
add a comment |
3 Answers
3
active
oldest
votes
The answer is no it doesn't optimize out the allocation of the array
Basically, every time the predicate is called, it checks against the compiler generated class and initializes a new array to call the Contains
(as you can see here)
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Predicate<int> <>9__0_0;
internal bool <M>b__0_0(int i)
{
// bam!
int obj = new int[3];
RuntimeHelpers.InitializeArray(obj, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
return Enumerable.Contains(obj, i);
}
}
add a comment |
As @Michael Randall already wrote, it looks like it is not possible.
I agree, that your questioned code is nicely readable, having the list in the RemoveAll method. But to have the instance only once, I have three ideas of doing it:
int a = null;
foo.RemoveAll(i => (a ?? (a = new { 1, 3, 5 })).Contains(i));
This is actually yours, with little un-beatuness of needing an external variable.
foo = foo.Except(new { 1, 3, 5 }).ToList();
That's actually pretty nice solution using Linq.
new List<int>{1, 3, 5}.ForEach(x => foo.Remove(x));
new {1, 3, 5}.Iterate(x => foo.Remove(x));
This is something I'd do. In neary all of my code I have my Extension method "Iterate" to avoid the need of foreach. And also, i dont want to "toList" everything all the time to make a .ForEach(..)
static class Extensions
{
public static void Iterate<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
{
foreach (var item in source)
{
action.Invoke(item);
}
}
}
5
Beware,RemoveAll
performs vastly better that multiple calls toRemove
.
– Theodor Zoulias
2 days ago
add a comment |
Since the compiler is not that smart, we must outsmart him.
var foo = new List<int> { 1, 2, 3, 4, 5 };
var bar = new HashSet<int>() { 1, 3, 5 };
foo.RemoveAll(i => bar.Contains(i));
1
A hash set of 3 entries will surely not perform better, it would arguably (I have not measured) perform worse.
– Sefe
2 days ago
3
@Sefe While there is probably a difference between the hash set and the array, I think the point of this answer was to createbar
outside of the anonymous function so that's it's created only once and to avoid the creation overhead.
– Joshua Taylor
2 days ago
2
@Sefe what you say is true, but I think that the OP provided a trivial example just to illustrate a point. In a real world scenario the lists will be probably longer than that.
– Theodor Zoulias
2 days ago
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55531327%2flistt-removeall-efficiency-compiler-optimisation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
The answer is no it doesn't optimize out the allocation of the array
Basically, every time the predicate is called, it checks against the compiler generated class and initializes a new array to call the Contains
(as you can see here)
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Predicate<int> <>9__0_0;
internal bool <M>b__0_0(int i)
{
// bam!
int obj = new int[3];
RuntimeHelpers.InitializeArray(obj, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
return Enumerable.Contains(obj, i);
}
}
add a comment |
The answer is no it doesn't optimize out the allocation of the array
Basically, every time the predicate is called, it checks against the compiler generated class and initializes a new array to call the Contains
(as you can see here)
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Predicate<int> <>9__0_0;
internal bool <M>b__0_0(int i)
{
// bam!
int obj = new int[3];
RuntimeHelpers.InitializeArray(obj, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
return Enumerable.Contains(obj, i);
}
}
add a comment |
The answer is no it doesn't optimize out the allocation of the array
Basically, every time the predicate is called, it checks against the compiler generated class and initializes a new array to call the Contains
(as you can see here)
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Predicate<int> <>9__0_0;
internal bool <M>b__0_0(int i)
{
// bam!
int obj = new int[3];
RuntimeHelpers.InitializeArray(obj, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
return Enumerable.Contains(obj, i);
}
}
The answer is no it doesn't optimize out the allocation of the array
Basically, every time the predicate is called, it checks against the compiler generated class and initializes a new array to call the Contains
(as you can see here)
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Predicate<int> <>9__0_0;
internal bool <M>b__0_0(int i)
{
// bam!
int obj = new int[3];
RuntimeHelpers.InitializeArray(obj, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
return Enumerable.Contains(obj, i);
}
}
edited 2 days ago
kara
2,20031126
2,20031126
answered 2 days ago
Michael RandallMichael Randall
37.2k84171
37.2k84171
add a comment |
add a comment |
As @Michael Randall already wrote, it looks like it is not possible.
I agree, that your questioned code is nicely readable, having the list in the RemoveAll method. But to have the instance only once, I have three ideas of doing it:
int a = null;
foo.RemoveAll(i => (a ?? (a = new { 1, 3, 5 })).Contains(i));
This is actually yours, with little un-beatuness of needing an external variable.
foo = foo.Except(new { 1, 3, 5 }).ToList();
That's actually pretty nice solution using Linq.
new List<int>{1, 3, 5}.ForEach(x => foo.Remove(x));
new {1, 3, 5}.Iterate(x => foo.Remove(x));
This is something I'd do. In neary all of my code I have my Extension method "Iterate" to avoid the need of foreach. And also, i dont want to "toList" everything all the time to make a .ForEach(..)
static class Extensions
{
public static void Iterate<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
{
foreach (var item in source)
{
action.Invoke(item);
}
}
}
5
Beware,RemoveAll
performs vastly better that multiple calls toRemove
.
– Theodor Zoulias
2 days ago
add a comment |
As @Michael Randall already wrote, it looks like it is not possible.
I agree, that your questioned code is nicely readable, having the list in the RemoveAll method. But to have the instance only once, I have three ideas of doing it:
int a = null;
foo.RemoveAll(i => (a ?? (a = new { 1, 3, 5 })).Contains(i));
This is actually yours, with little un-beatuness of needing an external variable.
foo = foo.Except(new { 1, 3, 5 }).ToList();
That's actually pretty nice solution using Linq.
new List<int>{1, 3, 5}.ForEach(x => foo.Remove(x));
new {1, 3, 5}.Iterate(x => foo.Remove(x));
This is something I'd do. In neary all of my code I have my Extension method "Iterate" to avoid the need of foreach. And also, i dont want to "toList" everything all the time to make a .ForEach(..)
static class Extensions
{
public static void Iterate<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
{
foreach (var item in source)
{
action.Invoke(item);
}
}
}
5
Beware,RemoveAll
performs vastly better that multiple calls toRemove
.
– Theodor Zoulias
2 days ago
add a comment |
As @Michael Randall already wrote, it looks like it is not possible.
I agree, that your questioned code is nicely readable, having the list in the RemoveAll method. But to have the instance only once, I have three ideas of doing it:
int a = null;
foo.RemoveAll(i => (a ?? (a = new { 1, 3, 5 })).Contains(i));
This is actually yours, with little un-beatuness of needing an external variable.
foo = foo.Except(new { 1, 3, 5 }).ToList();
That's actually pretty nice solution using Linq.
new List<int>{1, 3, 5}.ForEach(x => foo.Remove(x));
new {1, 3, 5}.Iterate(x => foo.Remove(x));
This is something I'd do. In neary all of my code I have my Extension method "Iterate" to avoid the need of foreach. And also, i dont want to "toList" everything all the time to make a .ForEach(..)
static class Extensions
{
public static void Iterate<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
{
foreach (var item in source)
{
action.Invoke(item);
}
}
}
As @Michael Randall already wrote, it looks like it is not possible.
I agree, that your questioned code is nicely readable, having the list in the RemoveAll method. But to have the instance only once, I have three ideas of doing it:
int a = null;
foo.RemoveAll(i => (a ?? (a = new { 1, 3, 5 })).Contains(i));
This is actually yours, with little un-beatuness of needing an external variable.
foo = foo.Except(new { 1, 3, 5 }).ToList();
That's actually pretty nice solution using Linq.
new List<int>{1, 3, 5}.ForEach(x => foo.Remove(x));
new {1, 3, 5}.Iterate(x => foo.Remove(x));
This is something I'd do. In neary all of my code I have my Extension method "Iterate" to avoid the need of foreach. And also, i dont want to "toList" everything all the time to make a .ForEach(..)
static class Extensions
{
public static void Iterate<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
{
foreach (var item in source)
{
action.Invoke(item);
}
}
}
answered 2 days ago
MaliorMalior
798311
798311
5
Beware,RemoveAll
performs vastly better that multiple calls toRemove
.
– Theodor Zoulias
2 days ago
add a comment |
5
Beware,RemoveAll
performs vastly better that multiple calls toRemove
.
– Theodor Zoulias
2 days ago
5
5
Beware,
RemoveAll
performs vastly better that multiple calls to Remove
.– Theodor Zoulias
2 days ago
Beware,
RemoveAll
performs vastly better that multiple calls to Remove
.– Theodor Zoulias
2 days ago
add a comment |
Since the compiler is not that smart, we must outsmart him.
var foo = new List<int> { 1, 2, 3, 4, 5 };
var bar = new HashSet<int>() { 1, 3, 5 };
foo.RemoveAll(i => bar.Contains(i));
1
A hash set of 3 entries will surely not perform better, it would arguably (I have not measured) perform worse.
– Sefe
2 days ago
3
@Sefe While there is probably a difference between the hash set and the array, I think the point of this answer was to createbar
outside of the anonymous function so that's it's created only once and to avoid the creation overhead.
– Joshua Taylor
2 days ago
2
@Sefe what you say is true, but I think that the OP provided a trivial example just to illustrate a point. In a real world scenario the lists will be probably longer than that.
– Theodor Zoulias
2 days ago
add a comment |
Since the compiler is not that smart, we must outsmart him.
var foo = new List<int> { 1, 2, 3, 4, 5 };
var bar = new HashSet<int>() { 1, 3, 5 };
foo.RemoveAll(i => bar.Contains(i));
1
A hash set of 3 entries will surely not perform better, it would arguably (I have not measured) perform worse.
– Sefe
2 days ago
3
@Sefe While there is probably a difference between the hash set and the array, I think the point of this answer was to createbar
outside of the anonymous function so that's it's created only once and to avoid the creation overhead.
– Joshua Taylor
2 days ago
2
@Sefe what you say is true, but I think that the OP provided a trivial example just to illustrate a point. In a real world scenario the lists will be probably longer than that.
– Theodor Zoulias
2 days ago
add a comment |
Since the compiler is not that smart, we must outsmart him.
var foo = new List<int> { 1, 2, 3, 4, 5 };
var bar = new HashSet<int>() { 1, 3, 5 };
foo.RemoveAll(i => bar.Contains(i));
Since the compiler is not that smart, we must outsmart him.
var foo = new List<int> { 1, 2, 3, 4, 5 };
var bar = new HashSet<int>() { 1, 3, 5 };
foo.RemoveAll(i => bar.Contains(i));
answered 2 days ago
Theodor ZouliasTheodor Zoulias
19719
19719
1
A hash set of 3 entries will surely not perform better, it would arguably (I have not measured) perform worse.
– Sefe
2 days ago
3
@Sefe While there is probably a difference between the hash set and the array, I think the point of this answer was to createbar
outside of the anonymous function so that's it's created only once and to avoid the creation overhead.
– Joshua Taylor
2 days ago
2
@Sefe what you say is true, but I think that the OP provided a trivial example just to illustrate a point. In a real world scenario the lists will be probably longer than that.
– Theodor Zoulias
2 days ago
add a comment |
1
A hash set of 3 entries will surely not perform better, it would arguably (I have not measured) perform worse.
– Sefe
2 days ago
3
@Sefe While there is probably a difference between the hash set and the array, I think the point of this answer was to createbar
outside of the anonymous function so that's it's created only once and to avoid the creation overhead.
– Joshua Taylor
2 days ago
2
@Sefe what you say is true, but I think that the OP provided a trivial example just to illustrate a point. In a real world scenario the lists will be probably longer than that.
– Theodor Zoulias
2 days ago
1
1
A hash set of 3 entries will surely not perform better, it would arguably (I have not measured) perform worse.
– Sefe
2 days ago
A hash set of 3 entries will surely not perform better, it would arguably (I have not measured) perform worse.
– Sefe
2 days ago
3
3
@Sefe While there is probably a difference between the hash set and the array, I think the point of this answer was to create
bar
outside of the anonymous function so that's it's created only once and to avoid the creation overhead.– Joshua Taylor
2 days ago
@Sefe While there is probably a difference between the hash set and the array, I think the point of this answer was to create
bar
outside of the anonymous function so that's it's created only once and to avoid the creation overhead.– Joshua Taylor
2 days ago
2
2
@Sefe what you say is true, but I think that the OP provided a trivial example just to illustrate a point. In a real world scenario the lists will be probably longer than that.
– Theodor Zoulias
2 days ago
@Sefe what you say is true, but I think that the OP provided a trivial example just to illustrate a point. In a real world scenario the lists will be probably longer than that.
– Theodor Zoulias
2 days ago
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55531327%2flistt-removeall-efficiency-compiler-optimisation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
25
try for your self sharplab.io
– Michael Randall
2 days ago
1
@MichaelRandall Great site. You should write an answer for this with an short example. This is interesseting for everybody, i think.
– kara
2 days ago
1
I'm really surprised but it looks like it does actually create a new instance of the 3 item array for each iteration inside the method
internal bool <M>b__0_0(int i)
.– maxp
2 days ago