C Arrays Designated Initializer in C# [duplicate] - c#

In the C++ Standard Template Library (STL), it is possible for example to create a vector consisting of multiple copies of the same element, using this constructor:
std::vector<double> v(10, 2.0);
This would create a vector of 10 doubles, initially set to 2.0.
I want to do a similar thing in C#, more specifically creating an array of n doubles with all elements initialized to the same value x.
I have come up with the following one-liner, relying on generic collections and LINQ:
double[] v = new double[n].Select(item => x).ToArray();
However, if an outsider would read this code I don't think it would be immediately apparent what the code actually does. I am also concerned about the performance, I suppose it would be faster to initialize the array elements via a for loop (although I haven't checked). Does anybody know of a cleaner and/or more efficient way to perform this task?

What about this?
double[] v = Enumerable.Repeat(x, n).ToArray();
EDIT: I just did a small benchmark; to create 1000 arrays of 100000 elements each, using a loop is about 3 times faster that Enumerable.Repeat.
Repeat
00:00:18.6875488
Loop
00:00:06.1628806
So if performance is critical, you should prefer the loop.

var arr = Enumerable.Repeat(x, n).ToArray();
Personally, I'd just use a regular array loop, though:
var arr = new double[n];
for(int i = 0 ; i < arr.Length ; i++) arr[i] = x;
More characters, but the array is demonstrably the right size from the outset - no iterative growth List<T>-style and final copy back. Also; simply more direct - and the JIT can do a lot to optimise the for(int i = 0 ; i < arr.Length ; i++) pattern (for arrays).

double[] theSameValues = Enumerable.Repeat(2.0, 10).ToArray();

Later versions of .NET have introduced an Array.Fill method. See usage:
double[] v = new double[n];
Array.Fill(v, 2.0);

the for each (or better the classic for) is always much faster than using Linq.
You should use the Linq expression only if it makes the code more readable

In VB.NET
Imports System.Linq
Dim n As Integer = 10
Dim colorArray = New Color(n - 1) {}.[Select](Function(item) Color.White).ToArray()

Related

Multi-dimensional or jagged array when dealing with matrix in C#?

I think the title is quite clear, so I'll just write some personal opinions here.
Consider a matrix of numbers, the equivalent representations in C# code are double[,] and double[][] respectively. When using multi-dimensional array (2D in this specific situation), It can be easily seen that one doesn't have to check either there is any null reference of double[] or the size of rows are the same, which allows a better understanding of the core problem. Also it descirbes the matrix more accurately from my point of view, since in most cases a matrix should be treated as a single entity rather than a list of arrays.
But using multi-dimensional array may result in more lines of code. If one wants to apply math operations on it, say, transposition, he would have to use nested loops like
var row = mat.GetLength(0);
var col = mat.GetLength(1);
var newmat = new double[col, row];
for (var i = 0; i < row; i++)
{
for (var j = 0; j < col; j++)
{
newmat[j, i] = mat[i, j];
}
}
With jagged array, he can simply write
var newmat = Enumerable.Range(0, mat[0].Length - 1).
Select(i => mat.Select(r => r[i]).ToArray()).ToArray();
I'm not sure which one is better. Usually I only create my own subroutine unless there is no solution provided by .Net, so I prefer the latter. But multi-dimensional array do have its advantages which I really like. Could anyone teach me about how to choose between them?
It's not about the lines of code that is the problem, but the efficiency of the code itself.
If you had a sparse matrix (matrix with almost all zeros), you want to use a jagged matrix because iterating through the two-dimensional matrix searching for non-zero elements would waste time.
However, if you had a matrix and you wanted to find its determinant, it would be simpler to use the method of co-factors on it. If you're not familiar with the method, it involves breaking up the matrix into smaller matrices, eventually to the 2x2 version where you can simply perform a*d-b*c. This isn't possible with jagged matrices.

Building int[] of increasing size

What is the easiest way to build an array of integers starting at 0 and increasing until a given point?
Background:
I have a struct that holds an int[] representing indexes of other arrays.
I would like to signify I want to use all indexes by filling this array with ints starting at 0 and increasing until int numTotalIndexes; I am sure there is a better way to do this than using a for loop.
Someone here showed me this little Linq trick
int[] numContacts = new int[]{ 32, 48, 24, 12};
String[][] descriptions = numContacts.Select(c => new string[c]).ToArray();
to build a jagged 2D array without loops (well it does, but it hides them and makes my code pretty) and I think there might be a nice little trick to accomplish what I want above.
You can use Enumerable.Range:
int[] intArray = Enumerable.Range(0, numTotalIndexes).ToArray();
You:
I am sure there is a better way to do this than using a for loop
Note that LINQ also uses loops, you simply don't see them. It's also not the most efficient way since ToArray doesn't know how large the array must be. However, it is a readable and short way.
So here is the (possibly premature-)optimized, classic way to initialize the array:
int[] intArray = new int[numTotalIndexes];
for(int i=0; i < numTotalIndexes; i++)
intArray[i] = i;
I'm not sure i understand your question at all but if going by your first line what you want is
var MySequencialArray = Enumerable.From(0,howmanyyouwant).ToArray();

Speed up loops on large data in C#

I have three nested loops from zero to n. n is a large number, around 12000th These three loops working on 2DList. It is actually a Floyd algorithm. At these large data it takes along time, could you advise me how to improve it? Thank you (Sorry for my english:) )
List<List<int>> distance = new List<List<int>>();
...
for (int i = 0; i < n; i++)
for (int v = 0; v < n; v++)
for (int w = 0; w < n; w++)
{
if (distance[v][i] != int.MaxValue &&
distance[i][w] != int.MaxValue)
{
int d = distance[v][i] + distance[i][w];
if (distance[v][w] > d)
distance[v][w] = d;
}
}
The first part of your if statement distance[v][i] != int.MaxValue can be moved outside of the iteration over w to reduce overhead in some cases. However, I have no idea how often your values are at int.MaxValue
You cannot change Floyd’s algorithm, its complexity is fixed (and it’s provably the most efficient solution to the general problem of finding all pairwise shortest path distances in a graph with negative edge weights).
You can only improve the runtime by making the problem more specific or the data set smaller. For a general solution you’re stuck with what you have.
Normally I would suggest using Parallel Linq - for example the Ray Tracer example, however this assumes that the items you're operating on are independent. In your example you are using results from a previous iteration, in the current one, making it impossible to parallelize.
As your code is quite simple and there isn't really any overhead, there's not really anything you can do to speed that up. As mentioned you could switch the Lists to arrays. You might also want to compare Double arithmetic to Integer arithmetic on your target machine.
After a simple look at your code, it seems that you might be heading for a overflow, as the condition check would not be able to block it.
In your code, the condition below adds no value, since we can have distance[v][i] < Int.MaxValue & distance[i][w] < Int.MaxValue but distance[v][i] + distance[i][w] > Int.Maxvalue.
if (distance[v][i] != int.MaxValue && distance[i][w] != int.MaxValue)
As the others have mentioned, the complexity is fixed so you don't exactly have many options there. However, you can use
Use arrays instead of lists, if possible.
Use an "unsafe" block with pointersemantics, this should decrease the time required to access your array data.
Check if you can parallelize your algorithm. In your case you could use multiple copies of your data (multiple copies to get rid of the need for synchronisation) and have several threads work on it (e.g. by splitting the range of the outerloop into some subranges (1-1000, 1001-2000 e.g.).

Initializing a C# array with multiple copies of the same element

In the C++ Standard Template Library (STL), it is possible for example to create a vector consisting of multiple copies of the same element, using this constructor:
std::vector<double> v(10, 2.0);
This would create a vector of 10 doubles, initially set to 2.0.
I want to do a similar thing in C#, more specifically creating an array of n doubles with all elements initialized to the same value x.
I have come up with the following one-liner, relying on generic collections and LINQ:
double[] v = new double[n].Select(item => x).ToArray();
However, if an outsider would read this code I don't think it would be immediately apparent what the code actually does. I am also concerned about the performance, I suppose it would be faster to initialize the array elements via a for loop (although I haven't checked). Does anybody know of a cleaner and/or more efficient way to perform this task?
What about this?
double[] v = Enumerable.Repeat(x, n).ToArray();
EDIT: I just did a small benchmark; to create 1000 arrays of 100000 elements each, using a loop is about 3 times faster that Enumerable.Repeat.
Repeat
00:00:18.6875488
Loop
00:00:06.1628806
So if performance is critical, you should prefer the loop.
var arr = Enumerable.Repeat(x, n).ToArray();
Personally, I'd just use a regular array loop, though:
var arr = new double[n];
for(int i = 0 ; i < arr.Length ; i++) arr[i] = x;
More characters, but the array is demonstrably the right size from the outset - no iterative growth List<T>-style and final copy back. Also; simply more direct - and the JIT can do a lot to optimise the for(int i = 0 ; i < arr.Length ; i++) pattern (for arrays).
double[] theSameValues = Enumerable.Repeat(2.0, 10).ToArray();
Later versions of .NET have introduced an Array.Fill method. See usage:
double[] v = new double[n];
Array.Fill(v, 2.0);
the for each (or better the classic for) is always much faster than using Linq.
You should use the Linq expression only if it makes the code more readable
In VB.NET
Imports System.Linq
Dim n As Integer = 10
Dim colorArray = New Color(n - 1) {}.[Select](Function(item) Color.White).ToArray()

Replace a substring in each element of a string array?

Hey, I have an array of strings and I want to replace a certain substring in each of those elements. Is there an easy way to do that besides iterating the array explicitly?
Thanks :-)
Ultimately, anything you do is going to do exactly that anyway. A simple for loop should be fine. There are pretty solutions involving lambdas, such as Array.ConvertAll / Enumerable.Select, but tbh it isn't necessary:
for(int i = 0 ; i < arr.Length ; i++) arr[i] = arr[i].Replace("foo","bar");
(the for loop has the most efficient handling for arrays; and foreach isn't an option due to mutating the iterator variable)
You could iterate the array implicitly
arrayOfStrings = arrayOfStrings.Select(s => s.Replace("abc", "xyz")).ToArray();

Categories