[英]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.