[C#] Вопрос о скорости
CLR via C# - в этой книге хорошо расписано, что и как нужно делать с массивами, когда нужна производительность
double[] a = new double[n];
fixed (double* p = &a[0])
{
for (int i = 0; i < n; i++)
{
x = p[i];
}
}
Еще там сказано, что такой способ может привести к разрушению памяти, нарушению безопасности типов и возникновению бреши в защите программы. Может кто-нибудь переведет это на русский язык?
Еще там сказано, что такой способ может привести к разрушению памяти, нарушению безопасности типов и возникновению бреши в защите программы. Может кто-нибудь переведет это на русский язык?если хоть чуток ошибешься, то программе настанет нехороший кирдык.
типа вот такого
т.к. небезопасный код будет быстрее только, если уже понимаешь все тонкости где происходит торможение программы.
К тому же JIT-compiler может сам выкинуть/соптимизировать проверки выхода за границы массива в некоторых случаях. По крайней мере в java это так.
А про ArrayList<T> вообще что можно сказать в плане производительности?
А про ArrayList<T> вообще что можно сказать в плане производительности?во-первых, такого класса вообще нет, есть List<T>
во-вторых, надо смотреть какие задачи
если задача - постоянно добавлять неопределенное кол-во чисел в коллекцию, то List - будет даже быстрее, чем простая реализация поверх массива
если задача - однажды создав коллекцию чисел потом ее часто использовать, то однозначно будет выигрышнее массив.
если же задача - постоянно добавлять/удалять числа из коллекции, то выигрышной будет уже какая-то более сложная структура данных (чем чисто массив, или List<T>)
это Рихтера что-ли книга про CLR?
При итерации по массиву явный for (int i = 0; i < yourArray.Length; ++i) работает намного быстрее, чем foreach(int yourValue in yourArray). По-видимому, JITter хорошо оптимизирует for, а foreach оставляет с enumerator-ами.
При итерации по массиву явный for (int i = 0; i < yourArray.Length; ++i) работает намного быстрее, чем foreach(int yourValue in yourArray). По-видимому, JITter хорошо оптимизирует for, а foreach оставляет с enumerator-ами.что тестилось?
.net 2.0 release, насколько я помню, выдавал уже одну и ту же скорость,
вот для .net 1.x - да, разница была
http://serugsandappliedscience.com/blog/2009/7/9/towards-c...
Сомневаюсь, что 9го июля 2009 года пользователь использовал первый .NET
Даже сомневаюсь, что второй.
Сомневаюсь, что 9го июля 2009 года пользователь использовал первый .NET
Даже сомневаюсь, что второй.
но вот такой код выдает одно и тоже время
var arr = Enumerable.Range(0, 10000000).Select(i => i * (2 * (i%2)-1.ToArray;
if (true)
{
var stopwatch = new System.Diagnostics.Stopwatch;
stopwatch.Start;
var sum2 = 0;
foreach (var i in arr)
sum2 += i;
stopwatch.Stop;
Console.WriteLine("{0}:{1}", sum2, stopwatch.Elapsed);
}
if (true)
{
var stopwatch = new System.Diagnostics.Stopwatch;
stopwatch.Start;
var sum = 0;
for (int i = 0; i < arr.Length; ++i)
sum += arr[i];
stopwatch.Stop;
Console.WriteLine("{0}:{1}", sum, stopwatch.Elapsed);
}
5000000:00:00:00.0123099у foreach-а будет больше времени, только если он не может догадаться, что на входе массив
5000000:00:00:00.0125784
это как раз бывает актуально для linq, т.к. там передается сплошной виртуальный ienumerable, что и мешает foreach-у распознать что на входе был массив.
хз, что они там тестировали, т.к. кода никакого нет.Ну вообще код там есть. Надо пройти по ссылке на "предыдущий пост".
Ну вообще код там есть. Надо пройти по ссылке на "предыдущий пост".если ты про ссылку http://pastebin.com/d10c04029, то она не рабочая
А, ок, заходил давно, может и не рабочая уже.
http://pastebin.com/f634d2a28
А вот что у меня при этом получается:
Foreach: mean=0,5000 var=0,0833 time=00:00:01.3586989
LINQ: mean=0,5000 var=0,0833 time=00:00:06.2992598
For: mean=0,5000 var=0,0833 time=00:00:00.8955397
For все еще быстрее, хотя разница не так заметна, как в том случае, если foreach получает на вход IEnumerable<T>
Вот вам обновленный код, где все функции на вход получают массив, а не интерфейс — А вот что у меня при этом получается:
Foreach: mean=0,5000 var=0,0833 time=00:00:01.3586989
LINQ: mean=0,5000 var=0,0833 time=00:00:06.2992598
For: mean=0,5000 var=0,0833 time=00:00:00.8955397
For все еще быстрее, хотя разница не так заметна, как в том случае, если foreach получает на вход IEnumerable<T>
а цепепе как?
Как справедливо отметил :
- если список не изменяется (1 раз создан и дальше используется, фиксированное количество элементов) - то делаешь его как массив (array)
- если по ходу работы изменяется - то списком (list)
- добавлю, что если при этом есть например задача проверки уникальности добавленного значения (то есть задача быстро выяснить принадлежит ли такой-то элемент множеству или нет или быстро получить его) - то разумно будет использовать словать (hashtable/dictionary).
P.S. я насчет производительности array и list никогда не задумывался =)
Типы эти использую скорее для того чтобы подчеркнуть семантику переменной
(изменяется или нет)
это Рихтера что-ли книга про CLR?Ага
Оставить комментарий
valkira
Если для программы очень критична производительность, и в ней активно используются очень длинные (порядка нескольких десятков тысяч) массивы данных (например, чисел типа double то что лучше использовать: обычный double[] или генерик ArrayList<double>? Последний гораздо удобнее в плане программирования, но насколько быстро он работает? Помогите советом, пожалуйста.