簡體   English   中英

應該更慢,但是更快。 為什么?

[英]Should be slower, but is faster. Why?

好的,讓我解釋一下。 在數組SL []中,我得到了指向列表的指針(我可以說列表分為幾小部分)。 所以我去SL [0]探索清單,然后去SL [1]探索清單.....

typedef struct TSL {
   struct TSL *next;
   int a;
} LSL;

LSL* SL[n] = {0}; // Array of pointers ;)

// Loop 1
void Find_All_Arc_SL()
{
   int i;
   LSL *tmp;
   for(i=0;i<n;i++)
   {
      tmp = SL[i];
      while(tmp != 0)
      {
         //printf("I find arc! %d -> %d",i,tmp->a);
         tmp = tmp -> next;
      }
   }
}

循環2。

typedef struct TAL {
   struct TAL *next;
   int v;
   int a;
 } LAL;
LAL *AL = 0;

void Find_All_Arc_AL()
{

  LAL *tmp;
  tmp = AL;

  while(tmp != 0)
  {
    //printf("I find arc %d -> %d \n",tmp->v,tmp->a);
    tmp = tmp -> next;
  };

}

在此功能中,我只是探索列表...而無需任何陣列等。

我的問題是:為什么Find_All_Arc_SL()總是比Find_All_Arc_AL()更快(毫秒Find_All_Arc_AL() 這些功能的工作原理幾乎相同,但是第一個(更快的)功能必須做額外的工作

您要求輸入完整的代碼。 在這里: U可以增加/減少n

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define n 5500

//Define struct
typedef struct TSL {
   struct TSL *next;
   int a;
 } LSL;


typedef struct TAL {
   struct TAL *next;
   int v;
   int a;
 } LAL;


// Poiner and array of pointers
LAL *AL = 0;
LSL* SL[n] = {0};

// To Calculate time
__int64 freq, start, end, diff;


// Build graph
void Create_AL()
{

    LAL *tmp;
    int p,k;

 for(p=0;p<n;p++)
 for(k=0;k<n;k++)
 {
     // Add arc
    tmp = malloc (sizeof(LAL));
    tmp->v = p;
    tmp->a = k;

     if(AL == 0) { tmp->next = 0; AL = tmp; }
     else { tmp->next = AL; AL = tmp; }  
 }
}

// Find arc
void Find_All_Arc_AL()
{

    LAL *tmp;
    tmp = AL;

    while(tmp != 0)
    {
     //printf("I found arc %d -> %d \n",tmp->v,tmp->a);
     tmp = tmp -> next;
    };

}


// Build graph
void Create_SL()
{

    LSL *tmp;
    int p,k;

 for(p=0;p<n;p++)
 for(k=0;k<n;k++)
 { 
    // Add arc
    tmp = malloc(sizeof(LSL));
    tmp -> a = k;       

    if(SL[p] == 0) {  tmp -> next = 0; SL[p] = tmp; }
    else { tmp -> next = SL[p]; SL[p] = tmp; }
    }

}


void Find_All_Arc_SL()
{

 int i;
    LSL *tmp;


    for(i=0;i<n;i++)
    {
    tmp = SL[i];

        while(tmp != 0)
        {
        //printf("I find arc %d -> %d \n", i, tmp->a);
        tmp = tmp -> next;
        }

    }

}


/**
 ** CALCULATE TIME!
 **/

void start_timer()
{
 freq = 0; start = 0; end = 0; diff = 0;

    QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
 QueryPerformanceCounter((LARGE_INTEGER*)&start);

}

void end_timer()
{

    QueryPerformanceCounter((LARGE_INTEGER*)&end);
    diff = ((end - start) * 1000) / freq;

}

int main(int argc, char *argv[])
{

Create_SL();

start_timer();
 Find_All_Arc_SL();
end_timer();
printf("Find_All_Arc_SL SEARCHING ALL ARC TOOK %d \n",diff);



 Create_AL();

start_timer();
 Find_All_Arc_AL();
end_timer();
printf("Find_All_Arc_AL SEARCHING ALL ARC TOOK %d \n",diff);



  system("PAUSE");  
  return 0;
}

這取決於您的數據。 您應該發布完整(有效)的示例。

另外,您如何測量時間? 您確定比較有意義嗎?

它看起來像一個記憶的東西。 由於訪問非緩存的內存可能要花費數百個或數千個CPU周期,因此內存訪問的數量和位置通常是影響程序性能的最重要因素。

在您的情況下,SL結構小於AL結構。 因此, Find_All_Arc_SL()具有較少的要訪問的內存,因此速度更快。

但是總的來說,該程序似乎太裸了,無法進行實際測試。

順便說一句:為了提高性能,應該使用更多的數組和更少的鏈接列表,因為數組比鏈接列表具有更好的局部性。

您需要遍歷該函數以獲得對速度的真實感受。 您也沒有預熱函數以獲取第一種方法的高速緩存中的值。 我得到的結果是:

Find_All_Arc_SL搜索所有弧圖6657

Find_All_Arc_AL搜索所有弧度6490

使用此代碼:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define n 500

//Define struct
typedef struct TSL {
   struct TSL *next;
   int a;
 } LSL;


typedef struct TAL {
   struct TAL *next;
   int v;
   int a;
 } LAL;


// Poiner and array of pointers
LAL *AL = 0;
LSL* SL[n] = {0};

// To Calculate time
__int64 freq, start, end, diff;


// Build graph
void Create_AL()
{

    LAL *tmp;
    int p,k;

 for(p=0;p<n;p++)
 for(k=0;k<n;k++)
 {
     // Add arc
    tmp = malloc (sizeof(LAL));
    tmp->v = p;
    tmp->a = k;

     if(AL == 0) { tmp->next = 0; AL = tmp; }
     else { tmp->next = AL; AL = tmp; }  
 }
}

// Find arc
void Find_All_Arc_AL()
{

    LAL *tmp;
    tmp = AL;

    while(tmp != 0)
    {
     //printf("I found arc %d -> %d \n",tmp->v,tmp->a);
     tmp = tmp -> next;
    };

}


// Build graph
void Create_SL()
{

    LSL *tmp;
    int p,k;

 for(p=0;p<n;p++)
 for(k=0;k<n;k++)
 { 
    // Add arc
    tmp = malloc(sizeof(LSL));
    tmp -> a = k;       

    if(SL[p] == 0) {  tmp -> next = 0; SL[p] = tmp; }
    else { tmp -> next = SL[p]; SL[p] = tmp; }
    }

}


void Find_All_Arc_SL()
{

 int i;
    LSL *tmp;


    for(i=0;i<n;i++)
    {
    tmp = SL[i];

        while(tmp != 0)
        {
        //printf("I find arc %d -> %d \n", i, tmp->a);
        tmp = tmp -> next;
        }

    }

}


/**
 ** CALCULATE TIME!
 **/

void start_timer()
{
 freq = 0; start = 0; end = 0; diff = 0;

    QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
 QueryPerformanceCounter((LARGE_INTEGER*)&start);

}

void end_timer()
{

    QueryPerformanceCounter((LARGE_INTEGER*)&end);
    diff = ((end - start) * 1000) / freq;

}

int main(int argc, char *argv[])
{
    int i;
Create_SL();

 Find_All_Arc_SL();
start_timer();
for(i=0;i<2000;++i)
 Find_All_Arc_SL();
end_timer();
printf("Find_All_Arc_SL SEARCHING ALL ARC TOOK %d \n",diff);



 Create_AL();

 Find_All_Arc_AL();
start_timer();
for(i=0;i<2000;++i)
 Find_All_Arc_AL();
end_timer();
printf("Find_All_Arc_AL SEARCHING ALL ARC TOOK %d \n",diff);



  system("PAUSE");  
  return 0;
}

編輯:為了降低我的價值,我必須降低n ,它是如此之大,在malloc為4gb的64位系統上, malloc返回0。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM