Производительность массивов против списков

Скажем, вам нужно иметь список / массив целых чисел, которые вам часто нужно перебирать, и я имею в виду очень часто. Причины могут быть разными, но говорят, что это находится в самом сердце внутренней петли обработки большого объема.

В общем, можно было бы выбрать использование списков (List) из-за их гибкости в размере. Кроме того, заявки на документацию msdn Списки используют массив внутри и должны выполняться так же быстро (быстрый просмотр с Reflector подтверждает это). Бесполезно, есть некоторые накладные расходы.

Кто-нибудь действительно измерил это? будет ли истребитель 6M раз через список принимать то же время, что и массив?

13 Solutions collect form web for “Производительность массивов против списков”

Очень легко измерить …

В небольшом количестве кода обработки с плотной петлей, где я знаю, что длина фиксирована, я использую массивы для этого крошечного бита микро-оптимизации; массивы могут быть немного быстрее, если вы используете индекс / для формы, но IIRC полагает, что это зависит от типа данных в массиве. Но если вам не нужна микро-оптимизация, прост и используйте List и т. Д.

Конечно, это применимо только в том случае, если вы читаете все данные; словарь будет быстрее для поиска по ключевым словам.

Вот мои результаты, используя «int» (второе число – контрольная сумма, чтобы убедиться, что все они сделали ту же работу):

(отредактировано, чтобы исправить ошибку)

 List/for: 1971ms (589725196) Array/for: 1864ms (589725196) List/foreach: 3054ms (589725196) Array/foreach: 1860ms (589725196) 

на основе испытательной установки:

 using System; using System.Collections.Generic; using System.Diagnostics; static class Program { static void Main() { List list = new List(6000000); Random rand = new Random(12345); for (int i = 0; i < 6000000; i++) { list.Add(rand.Next(5000)); } int[] arr = list.ToArray(); int chk = 0; Stopwatch watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { int len = list.Count; for (int i = 0; i < len; i++) { chk += list[i]; } } watch.Stop(); Console.WriteLine("List/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { for (int i = 0; i < arr.Length; i++) { chk += arr[i]; } } watch.Stop(); Console.WriteLine("Array/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in list) { chk += i; } } watch.Stop(); Console.WriteLine("List/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in arr) { chk += i; } } watch.Stop(); Console.WriteLine("Array/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk); Console.ReadLine(); } } 

Короткий ответ:

цветовое значение

Array vs List vs Linked List

Более подробный ответ вы найдете по следующей ссылке: https://stackoverflow.com/a/29263914/4423545

Я думаю, что производительность будет очень похожей. Накладные расходы, связанные с использованием List vs Array, – это IMHO, когда вы добавляете элементы в список, и когда список должен увеличивать размер массива, который он использует внутренне, когда достигается емкость массива.

Предположим, что у вас есть список с емкостью 10, тогда список увеличит его емкость, как только вы захотите добавить 11-й элемент. Вы можете уменьшить влияние производительности, инициализируя Емкость списка до количества элементов, которые он будет удерживать.

Но, чтобы выяснить, выполняется ли итерация над списком так же быстро, как итерация по массиву, почему бы вам не сравнить его?

 int numberOfElements = 6000000; List theList = new List (numberOfElements); int[] theArray = new int[numberOfElements]; for( int i = 0; i < numberOfElements; i++ ) { theList.Add (i); theArray[i] = i; } Stopwatch chrono = new Stopwatch (); chrono.Start (); int j; for( int i = 0; i < numberOfElements; i++ ) { j = theList[i]; } chrono.Stop (); Console.WriteLine (String.Format("iterating the List took {0} msec", chrono.ElapsedMilliseconds)); chrono.Reset(); chrono.Start(); for( int i = 0; i < numberOfElements; i++ ) { j = theArray[i]; } chrono.Stop (); Console.WriteLine (String.Format("iterating the array took {0} msec", chrono.ElapsedMilliseconds)); Console.ReadLine(); 

В моей системе; итерация по массиву заняла 33 мсек; итерация по списку заняла 66 мсек.

Честно говоря, я не ожидал, что вариация будет такой. Итак, я поместил свою итерацию в цикл: теперь я выполняю итерацию 1000 раз. Результаты:

итерация списка заняла 67146 мсек, итерация массива заняла 40821 мс

Теперь вариация уже не такая большая, но все же ...

Поэтому я запустил .NET Reflector и получатель индексатора classа List, выглядит так:

 public T get_Item(int index) { if (index >= this._size) { ThrowHelper.ThrowArgumentOutOfRangeException(); } return this._items[index]; } 

Как вы можете видеть, при использовании индексатора списка List выполняет проверку того, не выходите ли вы из границ внутреннего массива. Эта дополнительная проверка связана со стоимостью.

если вы просто получаете одно значение из (не в цикле), то оба проверяют границы (вы помните, что в управляемом кодовом коде), это список, который он делает дважды. См. Примечания позже, почему это, вероятно, не имеет большого значения.

Если вы используете свой собственный for (int int i = 0; i

  • Массив:
    • удаляется проверка границ
  • Списки
    • выполняется проверка границ

Если вы используете foreach, тогда ключевое различие заключается в следующем:

  • Массив:
    • для управления итерацией не выделяется объект
    • удаляется проверка границ
  • Список через переменную, известную как List.
    • переменная управления итерацией выделена в стеке
    • выполняется проверка границ
  • Список через переменную, известную как IList.
    • переменная управления итерацией является выделенной кучей
    • Выполняется также проверка границ. Значения списков не могут быть изменены во время foreach, тогда как массив может быть.

Проверка границ часто не имеет большого значения (особенно если вы находитесь на процессоре с глубоким конвейером и outlookом ветвления – норма для большинства этих дней), но только ваше собственное профилирование может сказать вам, если это проблема. Если вы находитесь в частях своего кода, где избегаете распределения кучи (хорошими примерами являются библиотеки или реализация hash-кодов), то при условии, что переменная набирается как List not IList, она избежит этой ошибки. Как всегда, если это имеет значение.

[ См. Также этот вопрос ]

Я изменил ответ Марка на использование фактических случайных чисел и фактически выполнил ту же работу во всех случаях.

Результаты:

          для foreach
 Массив: 1575 мс 1575 мс (+ 0%)
 Список: 1630ms 2627ms (+ 61%)
          (+ 3%) (+ 67%)

 (Контрольная сумма: -1000038876)

Скомпилирован как выпуск под VS 2008 SP1. Работа без отладки на Q6600@2.40GHz, .NET 3.5 SP1.

Код:

 class Program { static void Main(string[] args) { List list = new List(6000000); Random rand = new Random(1); for (int i = 0; i < 6000000; i++) { list.Add(rand.Next()); } int[] arr = list.ToArray(); int chk = 0; Stopwatch watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { int len = list.Count; for (int i = 0; i < len; i++) { chk += list[i]; } } watch.Stop(); Console.WriteLine("List/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { int len = arr.Length; for (int i = 0; i < len; i++) { chk += arr[i]; } } watch.Stop(); Console.WriteLine("Array/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in list) { chk += i; } } watch.Stop(); Console.WriteLine("List/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in arr) { chk += i; } } watch.Stop(); Console.WriteLine("Array/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk); Console.WriteLine(); Console.ReadLine(); } } 

Измерения хороши, но вы получите значительно разные результаты в зависимости от того, что вы делаете именно в своем внутреннем цикле. Измерьте свою ситуацию. Если вы используете multithreading, это просто нетривиальная деятельность.

Действительно, если вы выполняете некоторые сложные вычисления внутри цикла, производительность индексатора индекса по сравнению с индексом списка может быть настолько незначительно мала, что в конечном итоге это не имеет значения.

Не пытайтесь добавить емкость, увеличивая количество элементов.

Представление

 List For Add: 1ms Array For Add: 2397ms 

  Stopwatch watch; #region --> List For Add < -- List intList = new List(); watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 60000; rpt++) { intList.Add(rand.Next()); } watch.Stop(); Console.WriteLine("List For Add: {0}ms", watch.ElapsedMilliseconds); #endregion #region --> Array For Add < -- int[] intArray = new int[0]; watch = Stopwatch.StartNew(); int sira = 0; for (int rpt = 0; rpt < 60000; rpt++) { sira += 1; Array.Resize(ref intArray, intArray.Length + 1); intArray[rpt] = rand.Next(); } watch.Stop(); Console.WriteLine("Array For Add: {0}ms", watch.ElapsedMilliseconds); #endregion 

Вот тот, который использует словари, IEnumerable:

 using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; static class Program { static void Main() { List list = new List(6000000); for (int i = 0; i < 6000000; i++) { list.Add(i); } Console.WriteLine("Count: {0}", list.Count); int[] arr = list.ToArray(); IEnumerable Ienumerable = list.ToArray(); Dictionary dict = list.ToDictionary(x => x, y => true); int chk = 0; Stopwatch watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { int len = list.Count; for (int i = 0; i < len; i++) { chk += list[i]; } } watch.Stop(); Console.WriteLine("List/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { for (int i = 0; i < arr.Length; i++) { chk += arr[i]; } } watch.Stop(); Console.WriteLine("Array/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in Ienumerable) { chk += i; } } Console.WriteLine("Ienumerable/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in dict.Keys) { chk += i; } } Console.WriteLine("Dict/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in list) { chk += i; } } watch.Stop(); Console.WriteLine("List/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in arr) { chk += i; } } watch.Stop(); Console.WriteLine("Array/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in Ienumerable) { chk += i; } } watch.Stop(); Console.WriteLine("Ienumerable/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in dict.Keys) { chk += i; } } watch.Stop(); Console.WriteLine("Dict/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk); Console.ReadLine(); } } 

Поскольку List <> использует внутренние массивы, базовая производительность должна быть одинаковой. Две причины, почему Список может быть немного медленнее:

  • Чтобы найти элемент в списке, вызывается метод List, который выполняет поиск в базовом массиве. Поэтому вам нужен дополнительный метод. С другой стороны, компилятор может это распознать и оптимизировать «ненужный» вызов.
  • Компилятор может сделать некоторые специальные оптимизации, если он знает размер массива, который он не может сделать для списка неизвестной длины. Это может привести к повышению производительности, если у вас есть только несколько элементов в вашем списке.

Чтобы проверить, имеет ли это значение для вас, вероятно, лучше всего настроить опубликованные функции синхронизации на список размера, который вы планируете использовать, и посмотреть, как результаты для вашего частного случая.

Я был обеспокоен тем, что Benchmarks, опубликованные в других ответах, по-прежнему оставляют место для компилятора для оптимизации, исключения или объединения циклов, поэтому я написал один, который:

  • Используемые непредсказуемые входы (случайные)
  • Выполняет вычисление с результатом, напечатанным на консоли
  • Изменяет входные данные при каждом повторении

Результат, поскольку прямой массив имеет на 250% лучшую производительность, чем доступ к массиву, завернутому в IList:

  • Доступ к 1 миллиарду массивов: 4000 мс
  • 1 миллиард списков: 10000 мс
  • 100 миллионов обращений к массиву: 350 мс
  • 100 миллионов обращений к списку: 1000 мс

Вот код:

 static void Main(string[] args) { const int TestPointCount = 1000000; const int RepetitionCount = 1000; Stopwatch arrayTimer = new Stopwatch(); Stopwatch listTimer = new Stopwatch(); Point2[] points = new Point2[TestPointCount]; var random = new Random(); for (int index = 0; index < TestPointCount; ++index) { points[index].X = random.NextDouble(); points[index].Y = random.NextDouble(); } for (int repetition = 0; repetition <= RepetitionCount; ++repetition) { if (repetition > 0) { // first repetition is for cache warmup arrayTimer.Start(); } doWorkOnArray(points); if (repetition > 0) { // first repetition is for cache warmup arrayTimer.Stop(); } if (repetition > 0) { // first repetition is for cache warmup listTimer.Start(); } doWorkOnList(points); if (repetition > 0) { // first repetition is for cache warmup listTimer.Stop(); } } Console.WriteLine("Ignore this: " + points[0].X + points[0].Y); Console.WriteLine( string.Format( "{0} accesses on array took {1} ms", RepetitionCount * TestPointCount, arrayTimer.ElapsedMilliseconds ) ); Console.WriteLine( string.Format( "{0} accesses on list took {1} ms", RepetitionCount * TestPointCount, listTimer.ElapsedMilliseconds ) ); } private static void doWorkOnArray(Point2[] points) { var random = new Random(); int pointCount = points.Length; Point2 accumulated = Point2.Zero; for (int index = 0; index < pointCount; ++index) { accumulated.X += points[index].X; accumulated.Y += points[index].Y; } accumulated /= pointCount; // make use of the result somewhere so the optimizer can't eliminate the loop // also modify the input collection so the optimizer can merge the repetition loop points[random.Next(0, pointCount)] = accumulated; } private static void doWorkOnList(IList points) { var random = new Random(); int pointCount = points.Count; Point2 accumulated = Point2.Zero; for (int index = 0; index < pointCount; ++index) { accumulated.X += points[index].X; accumulated.Y += points[index].Y; } accumulated /= pointCount; // make use of the result somewhere so the optimizer can't eliminate the loop // also modify the input collection so the optimizer can merge the repetition loop points[random.Next(0, pointCount)] = accumulated; } 

Поскольку у меня был подобный вопрос, это помогло мне быстро начать.

Мой вопрос немного более конкретный, «что является самым быстрым методом для реализации рефлексивного массива»

Тестирование, выполненное Марком Гравелем, показывает много, но не точное время доступа. Его время включает в себя цикл по массиву и спискам. Поскольку я также придумал третий метод, который я хотел протестировать, «Словарь», просто для сравнения, я расширил тестовый код.

Firts, я делаю тест с использованием константы, которая дает мне определенное время, включая цикл. Это «голое» время, исключая фактический доступ. Затем я делаю тест с доступом к структуре субъекта, это дает мне и «накладные расходы», время, цикл и фактический доступ.

Разница между «голым» временем и временем «ограниченного времени» дает мне указание на время доступа к структуре.

Но насколько точно это время? Во время тестирования windows будут делать некоторое время нарезки для shure. У меня нет информации о разрезе времени, но я полагаю, что он равномерно распределен во время теста и порядка десятков мсек, что означает, что точность времени должна быть порядка +/- 100 мсек или около того. Немного грубая оценка? Во всяком случае, это источник систематической ошибки mearure.

Кроме того, тесты проводились в режиме «Отладка» без оптимизации. В противном случае компилятор может изменить фактический тестовый код.

Итак, я получаю два результата: один для константы, помеченный как «(c)», и один для доступа с пометкой «(n)», а разница «dt» говорит мне, сколько времени занимает фактический доступ.

И это результаты:

  Dictionary(c)/for: 1205ms (600000000) Dictionary(n)/for: 8046ms (589725196) dt = 6841 List(c)/for: 1186ms (1189725196) List(n)/for: 2475ms (1779450392) dt = 1289 Array(c)/for: 1019ms (600000000) Array(n)/for: 1266ms (589725196) dt = 247 Dictionary[key](c)/foreach: 2738ms (600000000) Dictionary[key](n)/foreach: 10017ms (589725196) dt = 7279 List(c)/foreach: 2480ms (600000000) List(n)/foreach: 2658ms (589725196) dt = 178 Array(c)/foreach: 1300ms (600000000) Array(n)/foreach: 1592ms (589725196) dt = 292 dt +/-.1 sec for foreach Dictionary 6.8 7.3 List 1.3 0.2 Array 0.2 0.3 Same test, different system: dt +/- .1 sec for foreach Dictionary 14.4 12.0 List 1.7 0.1 Array 0.5 0.7 

С лучшими оценками ошибок времени (как удалить системную ошибку измерения из-за временного сокращения?) Можно сказать больше о результатах.

Похоже, что List / foreach имеет самый быстрый доступ, но накладные расходы убивают его.

Разница между List / for и List / foreach невелика. Может быть, какая-то наличность?

Кроме того, для доступа к массиву не имеет значения, используете ли вы цикл for или цикл foreach . Результаты синхронизации и ее точность делают результаты «сравнимыми».

Использование словаря на сегодняшний день является самым медленным, я его рассматривал только потому, что на левой стороне (индекс) у меня есть разреженный список целых чисел, а не диапазон, который используется в этих тестах.

Вот модифицированный тестовый код.

 Dictionary dict = new Dictionary(6000000); List list = new List(6000000); Random rand = new Random(12345); for (int i = 0; i < 6000000; i++) { int n = rand.Next(5000); dict.Add(i, n); list.Add(n); } int[] arr = list.ToArray(); int chk = 0; Stopwatch watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { int len = dict.Count; for (int i = 0; i < len; i++) { chk += 1; // dict[i]; } } watch.Stop(); long c_dt = watch.ElapsedMilliseconds; Console.WriteLine(" Dictionary(c)/for: {0}ms ({1})", c_dt, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { int len = dict.Count; for (int i = 0; i < len; i++) { chk += dict[i]; } } watch.Stop(); long n_dt = watch.ElapsedMilliseconds; Console.WriteLine(" Dictionary(n)/for: {0}ms ({1})", n_dt, chk); Console.WriteLine("dt = {0}", n_dt - c_dt); watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { int len = list.Count; for (int i = 0; i < len; i++) { chk += 1; // list[i]; } } watch.Stop(); c_dt = watch.ElapsedMilliseconds; Console.WriteLine(" List(c)/for: {0}ms ({1})", c_dt, chk); watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { int len = list.Count; for (int i = 0; i < len; i++) { chk += list[i]; } } watch.Stop(); n_dt = watch.ElapsedMilliseconds; Console.WriteLine(" List(n)/for: {0}ms ({1})", n_dt, chk); Console.WriteLine("dt = {0}", n_dt - c_dt); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { for (int i = 0; i < arr.Length; i++) { chk += 1; // arr[i]; } } watch.Stop(); c_dt = watch.ElapsedMilliseconds; Console.WriteLine(" Array(c)/for: {0}ms ({1})", c_dt, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { for (int i = 0; i < arr.Length; i++) { chk += arr[i]; } } watch.Stop(); n_dt = watch.ElapsedMilliseconds; Console.WriteLine("Array(n)/for: {0}ms ({1})", n_dt, chk); Console.WriteLine("dt = {0}", n_dt - c_dt); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in dict.Keys) { chk += 1; // dict[i]; ; } } watch.Stop(); c_dt = watch.ElapsedMilliseconds; Console.WriteLine("Dictionary[key](c)/foreach: {0}ms ({1})", c_dt, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in dict.Keys) { chk += dict[i]; ; } } watch.Stop(); n_dt = watch.ElapsedMilliseconds; Console.WriteLine("Dictionary[key](n)/foreach: {0}ms ({1})", n_dt, chk); Console.WriteLine("dt = {0}", n_dt - c_dt); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in list) { chk += 1; // i; } } watch.Stop(); c_dt = watch.ElapsedMilliseconds; Console.WriteLine(" List(c)/foreach: {0}ms ({1})", c_dt, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in list) { chk += i; } } watch.Stop(); n_dt = watch.ElapsedMilliseconds; Console.WriteLine(" List(n)/foreach: {0}ms ({1})", n_dt, chk); Console.WriteLine("dt = {0}", n_dt - c_dt); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in arr) { chk += 1; // i; } } watch.Stop(); c_dt = watch.ElapsedMilliseconds; Console.WriteLine(" Array(c)/foreach: {0}ms ({1})", c_dt, chk); chk = 0; watch = Stopwatch.StartNew(); for (int rpt = 0; rpt < 100; rpt++) { foreach (int i in arr) { chk += i; } } watch.Stop(); n_dt = watch.ElapsedMilliseconds; Console.WriteLine("Array(n)/foreach: {0}ms ({1})", n_dt, chk); Console.WriteLine("dt = {0}", n_dt - c_dt); 

В некоторых кратких тестах я нашел комбинацию из двух, чтобы быть лучше в том, что я назвал бы достаточно интенсивной математикой:

Тип: List

Время: 00: 00: 05.1861300

Тип: List>

Время: 00: 00: 05.7941351

Тип: double[rows * columns]

Время: 00: 00: 06.0547118

Выполнение кода:

 int rows = 10000; int columns = 10000; IMatrix Matrix = new IMatrix(rows, columns); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int r = 0; r < Matrix.Rows; r++) for (int c = 0; c < Matrix.Columns; c++) Matrix[r, c] = Math.E; for (int r = 0; r < Matrix.Rows; r++) for (int c = 0; c < Matrix.Columns; c++) Matrix[r, c] *= -Math.Log(Math.E); stopwatch.Stop(); TimeSpan ts = stopwatch.Elapsed; Console.WriteLine(ts.ToString()); 

Мне жаль, что у нас не было таких высокоуровневых аппаратных ускорительных classов Matrix, как .NET Team, с classом System.Numerics.Vectors !

C # может быть лучшим языком ML с немного большей работой в этой области!

  • Как сгладить список в список без принуждения?
  • Коллекция была изменена; операция enums не может выполняться в ArrayList
  • Преобразовать список Scala в кортеж?
  • Конкатенация списка Scala, ::: vs ++
  • Проверьте, находится ли массив внутри списка в lisp
  • Список связанных с MIPS
  • Как получить количество элементов в списке в Python?
  • Найти полномочия 2 в списке Prolog
  • Android Endless List
  • Android Swipe в списке
  • Использование LINQ для удаления элементов из списка
  • Давайте будем гением компьютера.