2016年4月28日 星期四

C++ vector 複製

在C++的stl::vector 裡

如果想要複製一個vector到另一個vector的話有太多種方法

1.使用for 直接複製(速度最慢)

for(int i = 0; i < original.size(); ++i)
    new_vector[i] = original[i];

2.使用vector.assign()

new_vector.assign(original.begin(), original.end());

個人覺得這是最佳解,速度比起上一個快很多

3.使用vector.insert()

new_vector.reserve(original.size());
new_vector.insert(new_vector.end(), original.begin(), original.end())
insert也可以使用在把兩個vector合併(append)
用法就與上面類似了,就是reserve的時候也要加上new_vector的大小

4.使用copy constructor

new_vector = vector(original);
這個方法稍微測試了一下,好像不是真正的去複製
只是把new_vector指向了original的記憶體位置
也就是說new_vector跟original是同一個物件
動了其中一個兩個都會改變
也就是彼此是彼此的別名(我在說啥XD)

2016年4月12日 星期二

存取記憶體影響效能

最近在寫論文的程式時有些發現

在我的程式裡有這麼一段

deque<int> new_crossing(y2 - y1 + 1);
for (int i = 0; i <= y2 - y1; i++)
{
 int parent_crossing, child_crossing;

 if (bound.y > i + y1 || bound.br().y - 1 < i + y1)
  parent_crossing = 0;
 else
  parent_crossing = crossings[i + y1 -bound.y];

 if (child->bound.y > i + y1 || child->bound.br().y - 1 < i + y1)
  child_crossing = 0;
 else
  child_crossing = child->crossings[i + y1 - child->bound.y];

 new_crossing[i] = parent_crossing + child_crossing;
}

crossings = new_crossing;
內容就是要把parent_crossing與child_crossing 對齊地合起來(依照它們的y座標) 總之我偷懶的直接創了一個最可容納parent_crossing與child_crossing的deque
這樣的作法會不斷地創造新的deque,並且再把舊的deque給丟棄
一開始也只是先求有再求好,就不是這麼注重效能了
沒想到最近我發現了Visual Studio裡面有效能分析的工具
一分析下去...原來我在這一小段程式碼耗了將近2/3的時間
再來就是這一段了

vector<bool> pixel_accessible(height*width, false);
vector<bool> pixel_accumulated(height*width, false);
這是一個與影像大小相同的mask
用來檢查每個pixel的狀態
我發現用vector來存boolean,然後用operator[]存取這個mask也是極度地沒有效率
原因就不是很清楚了
後來把它改為用int存,而且記憶體是自己向作業系統要,效能又在提升一倍
只能說沒有效率的資料結構或是記憶體使用
把程式速度拖累個好幾倍是很常見的~