Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Скорость доступа к массиву

41K
22 июля 2009 года
gaga
44 / / 22.07.2009
Здравствуйте. Начал программировать для системы, где важна производительность. И возник такой вопрос: есть ли разница в скорости работы при статическом и динамическом выделении памяти?
 
Код:
class A{
int mass1[10];
int *mass2 = new int[10];
void foo() { mass1[1]++; }
void bar() { mass2[1]++; }
}

т.е. отработает ли foo быстрее bar? А если память под mass2 выделять для не константного кол-ва элементов?
И вообще, где можно почитать про эффективность различных методов на с++?
842
22 июля 2009 года
sigmov
301 / / 16.09.2008
Цитата: gaga
Здравствуйте. Начал программировать для системы, где важна производительность. И возник такой вопрос: есть ли разница в скорости работы при статическом и динамическом выделении памяти?
 
Код:
class A{
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];), потому как для доступ к куче идет через указатель, не говоря уже о времени на выделение и освобождение кучи.

260
22 июля 2009 года
Ramon
1.1K / / 16.08.2003
А через что идет доступ к массиву в стеке, через не-указатель?
842
22 июля 2009 года
sigmov
301 / / 16.09.2008
Решил провести эксперимент:

Код:
int mass1[100];
    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

Следовательно я был не прав. И доступ к массиву в стеке идет тоже через укзатель, скорость доступа к элемнетам - одиноковая!
842
22 июля 2009 года
sigmov
301 / / 16.09.2008
Еще один эксперимент:
Теперь мы выделяем и освобождаем память непосредственно в цикле

Код:
int k;
    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

Как мы видим выделение и освобождение памяти в куче ест довольно много ресурсов.
А вот выделение/освобождение памяти в стеке - практически не затрачивает времени.
41K
22 июля 2009 года
gaga
44 / / 22.07.2009
Цитата: sigmov

...
Как мы видим выделение и освобождение памяти в куче ест довольно много ресурсов.
А вот выделение/освобождение памяти в стеке - практически не затрачивает времени.



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

41K
22 июля 2009 года
gaga
44 / / 22.07.2009
Провел испытания в полевых условиях, но весьма грубые. Надо будет разобраться потом. Получилось вот что(для 10 000 000 итераций, как в примерах выше):
при доступе к массивам, объявленным как глобальные переменные, разница в скорости получается менее 5 %. Не думаю, что тут дело собственно в скорости доступа к элементу массива, разница была бы существенней для такого количества вызовов.
А вот если массивы являются членами класса, то динамический массив оказался медленней почти в два раза! И для статического время оказалось больше на 10%.
Надо будет потом продумать тестовый код и попробовать еще раз, уж больно странно получается
5
22 июля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: gaga
А вот если массивы являются членами класса, то динамический массив оказался медленней почти в два раза!


Грубая оценка:

Вычисление адреса элемента тут не настолько тривиально: а) сперва вычисление адреса размещение объекта, б) далее смещение указателя на массив относительно начала объекта, в) затем вычисление смещения в массиве.

Цитата: gaga
И для статического время оказалось больше на 10%.

Здесь к вычислению смещения массива (в) добавляется только вычисление смещения внутри объекта (б).



Кроме того, нужно не забывать про кэш-память процессора и предсказания переходов процессором. При определенной организации кода и то и другое может работать из ряда вон плохо. Об оптимизации кстати, писал товарищ К.Касперски в книжке "Техника оптимизации программ".

3
22 июля 2009 года
Green
4.8K / / 20.01.2000
Цитата: hardcase

Кроме того, нужно не забывать про кэш-память процессора и предсказания переходов процессором. При определенной организации кода и то и другое может работать из ряда вон плохо. Об оптимизации кстати, писал товарищ К.Касперски в книжке "Техника оптимизации программ".


Не храните большие массивы на стеке!
Это сильно бьет по производительности.

Выяснено на практике в скандальной теме:
http://forum.codenet.ru/showthread.php?t=17339&highlight=%F1%F2%F0%E0%ED%FB&page=14

:)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог