C++中三種傳遞參數方法的效率分析


眾所周知,在C++中有三種參數傳遞的方式:

  • 按值傳遞(pass by value)
#include <iostream>
using namespace std;

void swap(int a,int b)
{
	int temp = a;
	a = b;
	b = temp;
}
int main()
{
	int a = 0, b = 1;
	cout << a << " " << b << endl;
	swap(a,b);
	cout << a << " " << b << endl;
	return 0;
}


最好理解的一種方式。調用函數本身不對實參進行操作,也就是說,即使形參的值在函數中發生了變化,實參的值也完全不會受到影響,仍為調用前的值。

  • 按址傳遞(pass by pointer)
#include <iostream>
using namespace std;

void swap(int* a,int* b)
{
   int* temp = a;
   a = b;
   b = temp;
}

int main()
{
   int a = 0, b = 1;
   cout << a << " " << b << endl;
   swap(a,b);
   cout << a << " " << b << endl;
   return 0;
}


這種方式在函數定義時將形參說明成指針。把實參的存儲地址傳送給對應的形參,從而使得形參指針和實參指針指向同一個地址。因此,被調用函數中對形參指針所指向的地址中內容的任何改變都會影響到實參

  • 引用傳遞(pass by reference)
#include <iostream>
using namespace std;

void swap(int &a,int &b)
{
	int temp = a;
	a = b;
	b = temp;
}

int main()
{
	int a = 0, b = 1;
	cout << a << " " << b << endl;
	swap(a,b);
	cout << a << " " << b << endl;
	return 0;
}


引用傳遞方式是在函數定義時在形參前面加上引用運算符“&”。如果以引用為參數,則既可以使得對形參的任何操作都能改變相應的數據,又使得函數調用顯得方便、自然。
本文主要討論采用這三種方法傳遞參數時函數的效率。

傳遞效率

這里所說傳遞效率,是說調用被調函數的代碼將實參傳遞到被調函數體內的過程,正如上面代碼中,這個過程就是函數main()中的 a、b 傳遞到函數swap()中的過程。這個效率不能一概而論。對於內建的 int char、short、long、float 等4字節或以下的數據類型而言,實際上傳遞時也只需要傳遞 1-4 個字節,而使用指針傳遞時在 32 位 cpu 中傳遞的是 32 位的指針,4 個字節,都是一條指令,這種情況下值傳遞和指針傳遞的效率是一樣的,而傳遞 double、long long 等 8 字節的數據時,在 32 位 cpu 中,其傳值效率比傳遞指針要慢,因為 8 個字節需要 2 次取完。而在 64 位的 cpu 上,傳值和傳址的效率是一樣的。再說引用傳遞,這個要看編譯器具體實現,引用傳遞最顯然的實現方式是使用指針,這種情況下與指針的效率是一樣的,而有些情況下編譯器是可以優化的,采用直接尋址的方式,這種情況下,效率比傳值調用和傳址調用都要快,與采用全局變量方式傳遞的效率相當。

再說自定義的數據類型 —— class struct 定義的數據類型。這些數據類型在進行傳值調用時生成臨時對象會執行構造函數,而且當臨時對象銷毀時會執行析構函數,如果構造函數和析構函數執行的任務比較多,或者傳遞的對象尺寸比較大,那么傳值調用的消耗就比較大。這種情況下,采用傳址調用和采用傳引用調用的效率大多數下相當,正如上面所說,某些情況下引用傳遞可能被優化,總體效率稍高於傳址調用。

執行效率

這里所說的執行效率,是指在被調用的函數體內執行時的效率。 因為傳值調用時,當值被傳到函數體內,臨時對象生成以后,所有的執行任務都是通過直接尋址的方式執行的,而指針和大多數情況下的引用則是以間接尋址的方式執行的,所以實際的執行效率會比傳值調用要低。如果函數體內對參數傳過來的變量進行操作比較頻繁,執行總次數又多的情況下,傳址調用和大多數情況下的引用參數傳遞會造成比較明顯的執行效率損失。

綜上所述,具體的執行效率要結合實際情況,通過比較傳遞過程的資源消耗和執行函數體消耗之和來選擇哪種情況比較合適。而就引用傳遞和指針傳遞的效率上比,引用傳遞的效率始終不低於指針傳遞,所以從這種意義上講,在c++中進行參數傳遞時優先使用引用傳遞而不是指針。

參考:C++中函數調用時的三種參數傳遞方式詳解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM