Скорость доступа к массиву
int mass1[10];
int *mass2 = new int[10];
void foo() { mass1[1]++; }
void bar() { mass2[1]++; }
}
т.е. отработает ли foo быстрее bar? А если память под mass2 выделять для не константного кол-ва элементов?
И вообще, где можно почитать про эффективность различных методов на с++?
int mass1[10];
int *mass2 = new int[10];
void foo() { mass1[1]++; }
void bar() { mass2[1]++; }
}
т.е. отработает ли foo быстрее bar? А если память под mass2 выделять для не константного кол-ва элементов?
И вообще, где можно почитать про эффективность различных методов на с++?
Ответ на ваш вопрос - положительный. данные из стека(int mass1[10];) доступны быстрее чем данные из кучи(int *mass2 = new int[10];), потому как для доступ к куче идет через указатель, не говоря уже о времени на выделение и освобождение кучи.
int *mass2 = new int[100];
int k;
const int iters = 10000000;
DateTime M =DateTime::Now;
for(int i=0;i<iters;i++)
{
for(int j=0;j<100;j++)
mass2[j]=j;
k=mass2[0];
}
Console::WriteLine(DateTime::Now-M);
DateTime T =DateTime::Now;
for(int i=0;i<iters;i++)
{
for(int j=0;j<100;j++)
mass1[j]=j;
k=mass1[0];
}
Console::WriteLine(DateTime::Now-T);
Резкльтаты:
1) 1,54
2) 1,54
Следовательно я был не прав. И доступ к массиву в стеке идет тоже через укзатель, скорость доступа к элемнетам - одиноковая!
Теперь мы выделяем и освобождаем память непосредственно в цикле
const int iters = 10000000;
DateTime M =DateTime::Now;
for(int i=0;i<iters;i++)
{
int *mass2 = new int[100]; //Выделить в куче
for(int j=0;j<100;j++)
mass2[j]=j;
k=mass2[0];
delete mass2; //Освободить
}
Console::WriteLine(DateTime::Now-M);
DateTime T =DateTime::Now;
for(int i=0;i<iters;i++)
{
int mass1[100]; //Выделить в стеке
for(int j=0;j<100;j++)
mass1[j]=j;
k=mass1[0];
}
Console::WriteLine(DateTime::Now-T);
Результаты:
1) 3,52
2) 1,54
Как мы видим выделение и освобождение памяти в куче ест довольно много ресурсов.
А вот выделение/освобождение памяти в стеке - практически не затрачивает времени.
...
Как мы видим выделение и освобождение памяти в куче ест довольно много ресурсов.
А вот выделение/освобождение памяти в стеке - практически не затрачивает времени.
Да, ведь выделения на стеке фактически не происходит - компилятор, на сколько я понимаю, локальные переменные всегда располагает в одной области памяти.
Сейчас приду на работу и проведу эксперимент под QNX, посмотрим, будет ли там разница.
при доступе к массивам, объявленным как глобальные переменные, разница в скорости получается менее 5 %. Не думаю, что тут дело собственно в скорости доступа к элементу массива, разница была бы существенней для такого количества вызовов.
А вот если массивы являются членами класса, то динамический массив оказался медленней почти в два раза! И для статического время оказалось больше на 10%.
Надо будет потом продумать тестовый код и попробовать еще раз, уж больно странно получается
Грубая оценка:
Вычисление адреса элемента тут не настолько тривиально: а) сперва вычисление адреса размещение объекта, б) далее смещение указателя на массив относительно начала объекта, в) затем вычисление смещения в массиве.
Здесь к вычислению смещения массива (в) добавляется только вычисление смещения внутри объекта (б).
Кроме того, нужно не забывать про кэш-память процессора и предсказания переходов процессором. При определенной организации кода и то и другое может работать из ряда вон плохо. Об оптимизации кстати, писал товарищ К.Касперски в книжке "Техника оптимизации программ".
Кроме того, нужно не забывать про кэш-память процессора и предсказания переходов процессором. При определенной организации кода и то и другое может работать из ряда вон плохо. Об оптимизации кстати, писал товарищ К.Касперски в книжке "Техника оптимизации программ".
Не храните большие массивы на стеке!
Это сильно бьет по производительности.
Выяснено на практике в скандальной теме:
http://forum.codenet.ru/showthread.php?t=17339&highlight=%F1%F2%F0%E0%ED%FB&page=14
:)