0

I need class with array inside:

class FirstClass
{
     int x = 0;
     int y = 0;
}

class SecondClass
{
    FirstClass[] firstclass = ???????? // size of array is unknown
    OtherClass[][] otherclass = ???????? // i need also multidimensional array or array of arrays
}

Normally im using List<> for purposes like this, but today i need fastest possible solution (a lot of data to process), and i think Array should be faster than List (I've read somewhere that List is a lot slower than Array).

Question is - what to put into "????????" in my code?

Edit:

My class is a neural network object. Biggest array will contain learning data (100000+ data rows with 50+ fields, float or double datatype).

If Array is 1% faster than List - i need Array.

Kamil
  • 13,363
  • 24
  • 88
  • 183
  • 1
    `???????? = new List(expectedCapacity)` – I4V Jan 03 '13 at 20:14
  • 6
    Have you already built this using lists and found it's too slow? Do you have any *evidence* that the list part would be the bottleneck? If not, this is premature optimization. – Jon Skeet Jan 03 '13 at 20:14
  • It depends on what do you mean as 'process'. – Dennis Jan 03 '13 at 20:14
  • Could you clarify your intentions a little bit more? Why do you think the array would be a better solution than the list? What are you planning on doing? – Styxxy Jan 03 '13 at 20:15

5 Answers5

2

You cannot make an array until you know its exact size: unlike lists, arrays cannot grow*; once you give them a size, they keep that size forever. If you must have an array for processing, make a List<T> first, populate it, and then convert to an array with ToArray() method:

var firstClassList = new List<FirstClass>();
firtstClassList.Add(new FirstClass(123));
firtstClassList.Add(new FirstClass(456));
FirstClass firstClass[] = firtstClassList.ToArray();

var otherClassList = new List<List<OtherClass>>();
otherClassList.Add(new List<OtherClass>());
otherClassList[0].Add(OtherClass(10));
otherClassList[0].Add(OtherClass(11));
otherClassList.Add(new List<OtherClass>());
otherClassList[1].Add(OtherClass(20));
otherClassList[1].Add(OtherClass(21));
otherClassList[1].Add(OtherClass(22));
OtherClass otherClass[][] = otherClassList.Select(r => r.ToArray()).ToArray();

Note, however, that this is premature optimization: lists are very much as fast as arrays, but they offer a lot more flexibility. Replacing lists with arrays does not make sense, at least not before you profile.


* Calls of Array.Resize to change the size of the array do not count as "growing" the array, because you end up with a different array instance, and the one you were trying to "grow" gets thrown away immediately after being copied.
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • There is a method for array resize in .NET (it probably reallocates memory). I used it temporarily, maybe ill stay with it. – Kamil Jan 03 '13 at 20:34
  • @Kamil [`Array.Resize` documentation](http://msdn.microsoft.com/en-us/library/bb348051.aspx) specifically says that the array is re-allocated, - both when the size goes up, and when it goes down. In any event, it is not more efficient than `List`. – Sergey Kalinichenko Jan 03 '13 at 20:42
  • Your correct arrays cannot technically be resized, but you can use the Array.Resize method to return a new array of the specified size http://msdn.microsoft.com/en-us/library/bb348051.aspx – Leon Newswanger Jan 03 '13 at 20:44
  • My apologies I realized my mistake almost immediately upon hitting submit. – Leon Newswanger Jan 03 '13 at 20:45
  • Guys, what if i create zero-element array and i will use Add method? Im afraid, that Add method may reallocate whole array (like Resize) and it may take some time at 99999-th element. Finally array will grow to 40 megabytes or more. – Kamil Jan 03 '13 at 20:49
  • @Kamil `Add` will re-allocate memory as needed, but the overall time will be linear. You will be able to save some copying by sizing the lists initially to their minimal expected size. – Sergey Kalinichenko Jan 03 '13 at 20:51
  • Kamil you can declare a String[] = { }; for example load it without knowing it's initial size like the following.. try this example it works string[] variableNames = { };//new string[3]; for(var i = 0; i < variableNames.Length; i++) { variableNames[i] = "pos" + i.ToString(); } string allVariableNames = string.Join(",", variableNames); – MethodMan Jan 03 '13 at 20:58
  • OK. Thanks @dasblineklight for your time. Finally i decided, that I will use growing array, but i will resize it by 1000 elements, to reduce memory reallocation operations and copying that big array (i expect 40MBytes)It will take some time to implement something like this, but i really need every 1% of performance. – Kamil Jan 03 '13 at 21:01
  • 1
    @Kamil Incrementing by 1000 will give you worse asymptotic performance than `List`: with 40M items, your strategy will re-allocate 40,000 times, while List's will reallocate fewer than 25 times. It is rather unlikely that you'd be able to beat `List`, because Microsoft has already squeezed every 1% of performance from its implementation. – Sergey Kalinichenko Jan 03 '13 at 21:07
  • Its 100000 items, 40MBytes is estimated memory usage. I will make 1000 element list and after 1000 "insert" iterations I will resize it to 2000 elements (etc.) – Kamil Jan 03 '13 at 22:12
1

If you are unsure of the size of the Arrays, you may want to consider using a different type of collection, such as a List<FirstClass> as you mentioned or an ArrayList etc.

Performance-wise, until you have actually tested the data, you may be fine using a List and if you still have issues or bottlenecks, consider using an Array or some more efficient structure. (The run times shouldn't differ too greatly unless you are working with very large sets of data.)

(There is always the option to convert your lists to arrays as well.)

Rion Williams
  • 74,820
  • 37
  • 200
  • 327
1

Why would Array be faster than a List? See this question for a comparison of the running times.

The only case I can think of where an Array would beat a list is if you needed to search for an element, and the array was sorted so you could do a binary search. However, since you can use [] to index List<T>s in C#, that's a moot point.

Community
  • 1
  • 1
Chris Doggett
  • 19,959
  • 4
  • 61
  • 86
  • http://stackoverflow.com/questions/454916/performance-of-arrays-vs-lists it looks like array is at least 5% faster than list in `for` loop. 5% makes difference for me. – Kamil Jan 03 '13 at 20:40
  • @Kamil: Now that I know what you're using it for, that makes sense. Have you looked at AForge (http://code.google.com/p/aforge/)? – Chris Doggett Jan 03 '13 at 21:17
  • I saw AForge. I've read good article about it at codeproject (by Andrew Kirillov). I want to create own neural network implementation and implement multithreading. Upgrade like this on AForge library may be too complicated for me, im kind of amateur. – Kamil Jan 03 '13 at 22:25
  • They did have an example in their source, where the 2D array wasn't class level, but was instantiated when actually reading the data, like: int[][] input = new int[sampleSize][]; or something similar. That might be easier than trying to set the size at the beginning, unless you don't know how big your dataset will be until you've read all of it, in which case, throw it into a List, then use .ToArray(). Good luck with the NN. It's a fun project. – Chris Doggett Jan 04 '13 at 04:44
0
var list = new List<FirstClass>();
list.Add(object);

FirstClass[] firstClass = list.ToArray();

var listOfLists = new List<List<SecondClass>>();
var item1 = new List<SecondClass>();
item1.Add(anotherObject);
listOfLists.Add(item1);

SecondClass[][] secondClass = listsOfLists.Select(i => i.ToArray()).ToArray();
lante
  • 7,192
  • 4
  • 37
  • 57
-5

You can just instantiate them like this:

FirstClass[] firstclass = new FirstClass[];
OtherClass[][] otherclass = new OtherClass[][];

And then just use the Add method whenever you need to add an element:

firstclass.Add(new FirstClass());
user1610015
  • 6,561
  • 2
  • 15
  • 18
  • 1
    What language is this? Most certainly, it's not C#, [because in C# this does not compile](http://ideone.com/RvTEh0). – Sergey Kalinichenko Jan 03 '13 at 20:28
  • Error: "Array creation must have array size or array initializer". – Kamil Jan 03 '13 at 20:30
  • 2
    Better delete that and save your reputation :) – Kamil Jan 03 '13 at 20:31
  • Kamil you can have an Array defined without declaring initial size actually you can do it like this run the example and you will see that it works.. string[] variableNames = { };//new string[3]; for(var i = 0; i < variableNames.Length; i++) { variableNames[i] = "pos" + i.ToString(); } string allVariableNames = string.Join(",", variableNames); – MethodMan Jan 03 '13 at 20:57