I have an array of ints which has a number of negative values in:
var arrayExisting = new int[]{1,2,-1,3,5,-1,0,0,-1};
And another array with a corresponding set of values I want to insert into the first array:
var replacements = new int[]{7,6,5};
Is there a truly efficient way of doing this?
What I have currently is:
var newArray = arrayExisting.Select(val =>
{
if (val != -1) return val;
var ret = replacements[i];
i++;
return ret;
}).ToArray();
It's fairly quick. The arrays in question are only about 15 integers in length, and this might go up, but unlikely to exceed 100. The problem is that I have to do this over a quarter of a million times for my moderate test system, and the realistic system I am considering will involve about 10e10 iterations of this code!
I would use a for
loop and replace values in your original array in-place.
int replacementIndex = 0;
for (var i = 0; i < arrayExisting.Length; i++) {
if (arrayExisting[i] < 0) {
arrayExisting[i] = replacements[replacementIndex++];
}
}
This way you avoid the overhead creating a new array. If you need to create a new array you can create a new int[arrayExisting.Length]
Running a quick benchmark it seems that the for loop is ~4x faster, even in the worst case where you have to replace every single time and you construct a new array to hold the replacements.
Select: 12672
For: 3386
Here's the benchmark if you're intrested.
var loops = 1000000;
var arrayExisting = Enumerable.Repeat(-1, 1000).ToArray();
var replacements = Enumerable.Repeat(1, 1000).ToArray();
var selectTimer = Stopwatch.StartNew();
for (var j = 0; j < loops; j++)
{
var i = 0;
var newArray = arrayExisting.Select(val =>
{
if (val != -1) return val;
var ret = replacements[i];
i++;
return ret;
}).ToArray();
}
selectTimer.Stop();
var forTimer = Stopwatch.StartNew();
for (var j = 0; j < loops; j++)
{
var replaced = new int[arrayExisting.Length];
int replacementIndex = 0;
for (var i = 0; i < arrayExisting.Length; i++)
{
if (arrayExisting[i] < 0)
{
replaced[i] = replacements[replacementIndex++];
}
else
{
replaced[i] = arrayExisting[i];
}
}
}
forTimer.Stop();
Console.WriteLine("Select: " + selectTimer.ElapsedMilliseconds);
Console.WriteLine("For: " + forTimer.ElapsedMilliseconds);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With