2017-07-07 203 views
0

我看到What is the difference between memmove and memcpy?中接受的答案中指出的差異,它表示memmove might be very slightly slower than memcpymemmove與memcpy比較兩次的性能?

我們可以通過如下方式實現memmove的替代方案:分配一個臨時緩衝區,然後memcpy兩次(src - > tmp,tmp - > dest)。我的問題是:哪種方式更快,memmove還是替代方法?

+0

這取決於目標機器和實現。 –

+4

複製數據很慢。複製數據*兩次*會變慢。 'memmove' *可能會比'memcpy'慢,因爲它能夠處理重疊的內存,但是'memmove'仍然只能複製一次數據*。 –

+1

在您對時間感興趣的平臺上對其進行剖析。然而,你寫一個比memmove更好的memmove的機會似乎不大可能。 – xaxxon

回答

4

http://en.cppreference.com/w/cpp/string/byte/memmove

儘管被指定爲「好像」使用臨時緩衝區,這個功能的實際實現不承擔雙重複印或額外內存的開銷。對於小數值,它可能會加載並寫出寄存器;對於較大的塊,一種常用的方法(glibc和bsd libc)是如果目的地在源之前開始,則從緩衝區的開始向前複製字節,否則從結尾向後,當存在時回退到std :: memcpy根本沒有重疊。

因此,所有可能性的開銷都是一對條件分支。非常值得擔心大塊。

但值得記住的是std::memcpy是一個'魔術'功能,是兩種不同類型之間唯一合法的投射方式。

在C++中,這是非法的(未定義行爲):

union { 
    float a; 
    int b; 
} u; 

u.a = 10.0; 
int x = u.b; 

這是合法的:

float a = 10.0; 
int b; 
std::memcpy(std::addressof(b), std::addressof(a), size(b)); 

,並做你所期望的工會做什麼,如果你是一個C程序員。

1

std::memmove「可以是比std::memcpy非常輕微慢」(強調),因爲它必須首先檢查源和目標範圍是否重疊。在內部,這只是一對指針比較;如果沒有重疊或者目標在源代碼下面開始,它會調用std::memcpy;否則,它會調用std::memcpy的變體,從末尾開始複製。

總之,有只有區別在於初步比較;一旦完成,就像std::memcpy。不需要額外的緩衝區並將所有內容複製兩次。

0

Memcpy通常更快,因爲它不認爲目標和源可能重疊。

所以,如果你嘗試使用memcpy字符串abcd從位置X複製到X+2有可能得到的結果類似的memcpy

X+2 A B A A 

同時的memmove

X: A B C D 

後將保證你沒有丟失任何東西,因爲它使用中間緩衝區來存儲原始字符串。

在另一方面,你可以使用限定restrict的來源和目的地,這樣你可以告訴的memmove源和目標不重疊,並且像的memmove可能的情況下,你用選擇其他更快的算法這個限定詞。

詳情請參閱here