---
# System prepended metadata

title: 動態陣列和Linked list的Push back和Sum比較時間

---

動態陣列和Linked list的Push back和Sum比較時間
===
### Dynamic Array和Linked list的Push back和Sum比較程式
附註:使用DynamicArray時，需註解Linkedlist部分的code(包含struct linklist)，反之使用Vector時，亦然。
```cpp=
#include<iostream>
#include<vector>
#include <cstdlib> /* 亂數相關函數 */
#include <ctime>   /* 時間相關函數 */
#include <chrono>  // for high_resolution_clock
using namespace std;

struct node
{
  int data;
  node *next;
};

uint64_t powers_of_2[65] = {1,
                2,  4,  8,  16, 32, 64, 128,256,512,1024,
                2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,
                2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,
                2147483648,4294967296,8589934592,17179869184,34359738368,68719476736,137438953472,274877906944,549755813888,1099511627776,
                2199023255552,4398046511104,8796093022208,17592186044416,35184372088832,70368744177664,140737488355328,281474976710656,562949953421312,1125899906842624,
                2251799813685248,4503599627370496,9007199254740992,18014398509481984,36028797018963968,72057594037927936,144115188075855872,288230376151711744,576460752303423488,1152921504606846976,
                2305843009213693952,4611686018427387904,9223372036854775808,18446744073709551615
                };

///Linked list chronos
//std::chrono::nanoseconds  push_back_duration = std::chrono::high_resolution_clock::now() - std::chrono::high_resolution_clock::now();
//std::chrono::nanoseconds  insert_time_duration = std::chrono::high_resolution_clock::now() - std::chrono::high_resolution_clock::now();
//std::chrono::nanoseconds  next_point_duration = std::chrono::high_resolution_clock::now() - std::chrono::high_resolution_clock::now();

///Vector chronos
std::chrono::nanoseconds  vector_push_back_duration = std::chrono::high_resolution_clock::now() - std::chrono::high_resolution_clock::now();


///Linked List

class linked_list
{
private:
    node *head,*tail;
public:
    linked_list()
    {
        head = NULL;
        tail = NULL;
    }

    void add_node(int n)
    {
        ///sum
        //sum+=n;
        
        ///push back duration
        auto start_time = std::chrono::high_resolution_clock::now();
        node *tmp = new node;
        auto end_time = std::chrono::high_resolution_clock::now();


        push_back_duration += (end_time-start_time);


        ///insert data duration
        start_time = std::chrono::high_resolution_clock::now();
        tmp->data = n;
        end_time = std::chrono::high_resolution_clock::now();

        insert_time_duration += (end_time-start_time);

        ///next point duration
        start_time = std::chrono::high_resolution_clock::now();
        tmp->next = NULL;
        end_time = std::chrono::high_resolution_clock::now();

        next_point_duration += (end_time-start_time);

        if(head == NULL)
        {
            head = tmp;
            tail = tmp;
        }
        else
        {
            tail->next = tmp;
            tail = tail->next;
        }
    }
};



int main(){
    int i = 20;

    int times = 0;
    int x;
    
    ///sum
    //uint64_t sum = 0;

///linked list
    linked_list list_a[10];
    

    uint64_t average_push_back_duration = 0;
    uint64_t average_insert_time_duration = 0;
    uint64_t average_next_point_duration = 0;

///Vector
    vector<int> Dynamic_Array[10];

    uint64_t average_vector_push_back_duration = 0;


    uint64_t ncount = powers_of_2[i];


    cout<<i<<"'s power"<<endl;
    cout<<ncount<<endl;

    while(times<1){
        srand( time(NULL) );
        
        ///sum
        //sum = 0;

        //cin>>i;
        ncount = powers_of_2[i];

        while(ncount--){
            //cout<<ncount<<endl;
            x = rand();
            
            ///sum
            //sum+=x;

            ///Vector push_back
            auto start_time = std::chrono::high_resolution_clock::now();
            Dynamic_Array[times].push_back(x);
            auto end_time = std::chrono::high_resolution_clock::now();
            
            vector_push_back_duration += (end_time-start_time);

            ///linked list push_back
            list_a[times].add_node(x);

        }



        ///linked list Print Test
        //cout <<" Test " << times <<":"<<endl;
        //cout << "push_back time: " << push_back_duration.count() << " ns\n";
        //cout << "data_insert time: " << insert_time_duration.count() << " ns\n";
        //cout << "next_pointer time: " << next_point_duration.count() << " ns\n";

        ///Linked List summing
//        average_push_back_duration += push_back_duration.count();
//        average_insert_time_duration += insert_time_duration.count();
//        average_next_point_duration += next_point_duration.count();

        ///Vector Print Test
//        cout <<" Test " << times <<":"<<endl;
//        cout << "push_back time: " << vector_push_back_duration.count() << " ns\n";



        average_vector_push_back_duration += vector_push_back_duration.count();

        times++;
        //cout<<endl;
    }
    cout<<endl<<endl;

    ///cout Linked List average time
    average_push_back_duration = average_push_back_duration/10;
    average_insert_time_duration = average_insert_time_duration/10;
    average_next_point_duration = average_next_point_duration/10;

    cout<<"---------------------"<<endl;
    cout <<" Average Test : " <<endl;
    cout << "Final_push_back time: " << average_push_back_duration << " ns\n";
    cout << "Final_data_insert time: " << average_insert_time_duration << " ns\n";
    cout << "Final_next_pointer time: " << average_next_point_duration << " ns\n";

    ///cout Vector average time
    average_vector_push_back_duration = average_vector_push_back_duration;

    cout<<"---------------------"<<endl;
    cout <<" Average Test : " <<endl;
    cout << "Final_push_back time: " << average_vector_push_back_duration << " ns\n";

}

```


實驗報告:

1.	實驗結果: 
折線圖一代表Dynamic Array和Linked list的push back時間，以毫秒millisecond為單位，測量兩種方式在2的n次方(2^n)個資料執行的時間。
折線圖二則是Dynamic Array和Linked list加總2^n組資料的執行時間。
2^13至2^25的資料皆是做了10次在進行平均，而2^26以上的資料則受限設備只能計算一次。2^30無法計算，而是根據前面的資料推測得出。
根據實驗結果得出，Linked list無論是在Push back或隨機數相加的兩項任務皆較Dynamic Array花費了四倍近五倍的執行時間。我認為出現這類情況的原因是因為，Linked list相比Dynamic Array在新增data時，多了一個讀取pointer的過程，會多花時間。然而，Linked list多花的時間是固定的，若是pushed或sum的區域在陣列中間，而非push back時，由於Dynamic Array的資料位置是連續的，在插入資料時平均會需要動到陣列一半的資料，此時Dynamic Array執行時間便會超過Linked list.

Linked List Push back time verses Dynamic Array Push back time
Graph 1
![](https://i.imgur.com/tcV8cOw.png)

Linked List Sum time verses Dynamic Array Sum time
Graph 2
![](https://i.imgur.com/YqyKcRJ.png)

---
2. Dynamic Array 和Linked List 程式碼來源
Linked List Code:
![](https://i.imgur.com/sOVoZzd.png)

 
Linked List的部分，我參考了下列網站https://hackmd.io/@Zero871015/H12vTu8aX?type=view
Linked list 的概念是每次只給一格空間，用指標把每格空間串聯起來，一個指標接著一個指標。

我建立一個叫做節點node的型別，node有兩個部分 :
一個是當下node的資料data，和一個指向下一個node的指標*next
Add note函數則是負責增加新的節點(node)，但頭(head)和尾(tail)的部分需要另外判斷
這段程式符合上述講的Linked List概念，使用一格空間data來存資料，並使用指標next來連接不同的data。

Vector Code:
![](https://i.imgur.com/F5QGeTU.png)

 
Dynamic Array是C++標準函式庫的std::vector，因此是動態陣列



3. 實驗的程式碼:
程式碼放在開頭。
---

4. 心得、疑問、與遇到的困難:
這次作業是比較Linked List和 Dynamic Array之間的時間，在實驗的過程因為較不熟悉計時方面的函數，因此在stack overflow上尋找，在<time.h>和<chrono>兩函數之間比較。同時遇到第一個困難，當陣列數量較小時，測量的秒數小於time函數的顯示標準，因此得出的數值皆是0，而chrono函數的測量單位可測量nanosecond，因此選擇了chrono函數。遇到另一困難chrono函數使用的變數型別是duration型別，而非常用的int, float…等等，這問題也在查找chrono的cpp reference中找到答案。第三個遇到的困難是測試資料太大，常常測試到一半電腦便重開機，之後每次紀錄單筆測資在手動平均將問題解決。
	在實驗Linked list和Dynamic 時，我發現Linked list相較於Dynamic Array所用時間較慢了五倍的時間，我平常使用上也大都使用Vector之類的動態陣列，而較不常使用Linked list。我產生了疑問為何Linked list存在並仍然廣泛使用，而不會被Dynamic Array取代。因此查了Linked list和 Dynamic Array之間的特性得知，Linked list和Dynamic Array有幾大特性不同。
    


| 特性 | 動態陣列 | Linked List |
| -------- | -------- | -------- |
| 連續記憶體空間   | 是 | 可以非連續     |	
|型態 |	型別皆需相同|	不一定要相同|
插入/刪除元素	|麻煩，平均會動到一半的陣列	|方便，只需改變前後和自身指標
支援隨機存取|可支援|	可以，但需要在串列上增加功能
可靠度|	高|	低，若是指標斷裂，資料便遺失

---

結論，Dynamic Array和 Linked list在特性上有諸多不同，各有優缺，Linked list的優點不在於新增資料的速度，而是在使用的彈性和功能性上。
