Скорость: вызов по указателю или доступ по вектору? - PullRequest
0 голосов
/ 01 февраля 2012

Я хотел бы знать, какое решение может быть быстрее.Допустим, у нас есть вектор mB из 100 (или n) указателей на объекты B, каждый из которых содержит функцию foo (), возвращающую двойное значение:

Код 1:

int main () {
    vector<double> mA;
    for (int i=0; i<100; i++)
        mA.push_back(mB->at(i)->foo());
    for (int i=0; i<100; i++)
        double a = pow((mA.at(i))*(mA.at(i+1)),2);

    return 0;
}

Код 2:

int main () {
     for (int i=0; i<100; i++)
         double a = pow((mB->at(i)->foo()))*(mB->at(i+1)->foo())),2);

     return 0;
}

Код 1 сначала сохраняет двойное значение в векторе, поэтому у нас есть 100 обращений к функциям по указателям, а затем 100 + 100 обращений квектор мА.Во втором у нас есть 100 + 100, вызывающих функции через pointes.

1) Вызов по указателю медленнее, чем доступ .at () к вектору?2) какое решение лучше для получения более быстрого кода?Спасибо

Ответы [ 3 ]

0 голосов
/ 01 февраля 2012

Благодаря вашим предложениям я попробовал это:

#include <iostream>
#include <vector>
#include "A.h"
#include "B.h"
#include <Windows.h>
 using namespace std;

void StartTimer( _int64 *pt1 )
{
   QueryPerformanceCounter( (LARGE_INTEGER*)pt1 );
}

double StopTimer( _int64 t1 )
{
   _int64 t2, ldFreq;
   QueryPerformanceCounter( (LARGE_INTEGER*)&t2 );
   QueryPerformanceFrequency( (LARGE_INTEGER*)&ldFreq );
   return ((double)( t2 - t1 ) / (double)ldFreq) * 1000.0;
}

int main(){
_int64 t1;
StartTimer( &t1 );

 vector<B*> *mB = new vector<B*>;
for (int i=0; i<100; i++)
 mB->push_back(new B());
 A mA(mB);

 printf( "Time = %.3f\n", StopTimer( t1 ));

 system("Pause");
 return 0;
 }

A.cpp:

#include "A.h"

A::A(vector<B*> *mB)
{
 //code1:
 vector<double> mA;
 for (int i=0; i<100; i++)
  mA.push_back(mB->at(i)->foo());
  for (int i=0; i<99; i++)
  cout <<pow((mA.at(i))*(mA.at(i+1)),2)<<endl;
  //code 2:
  //for (int i=0; i<99; i++)
 //cout <<pow((mB->at(i)->foo())*(mB->at(i+1)->foo()),2)<<endl;

}

A::~A(void){}

B.cpp

#include "B.h"

B::B(void):value(10){} //firstly i used rand() maybe affects speed test
B::~B(void){}
double B::foo(){
return value;
 }

Результаты в срокскорость не ясна, потому что время меняется при каждом запуске отладки с обоими кодами, отскакивающими от 20 до 50 миллисекунд

РЕДАКТИРОВАТЬ: 100000 объектов: КОД 1: ~ 958 миллисекунд КОД 2: ~ 760 миллисекунд

0 голосов
/ 02 февраля 2012

Следующий фрагмент кода должен быть быстрее обеих ваших версий, потому что at() выполняет проверку привязки, а operator[] - нет.Последнее может привести к выходу за пределы вектора, отсюда и условности.

if (mB->size() >= 101)
    for (size_t i = 0; i < 100; i++)
        double a = (*mB)[i]->foo() * (*mB)[i]->foo();
0 голосов
/ 01 февраля 2012

Просто глядя на код, тот факт, что в первом фрагменте есть 2 цикла for, которые идут в 100, а во втором - только 1 for цикла, первый, вероятно, будет медленнее. Причина? Если проверки очень медленные, и цикл for содержит их несколько. Итак, первый фрагмент кода имеет двойное количество проверок if. Поэтому я не думаю, что разница между обоими способами доступа, о которых вы говорите, сыграет важную роль.

То, что вы можете попытаться сделать, это посмотреть на сборку, сгенерированную обоими, или вы можете использовать один из множества способов синхронизации. Поскольку у вас есть Visual Studio, вы можете попробовать QueryPerformanceCounter: http://support.microsoft.com/kb/815668

Попробуйте и сообщите нам результат!

PS. Я предложил изменить название вашего вопроса, так как вы сказали «Скорость», что было бы неправильно, так как вы сравниваете скорости. Вероятно, лучшим способом задать вопрос было бы «что быстрее, доступ ... и т. Д.», Но я не хотел менять его слишком сильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...