簡體   English   中英

C#指針與C ++指針

[英]C# pointers vs. C++ pointers

我一直在學習編程,我選擇C ++和C#編程作為第一語言。 更具體地說,我有一本舊的C書,有人讓我借用,我正在用它來學習C#。 我使用Visual Studio Express並使用C ++和C#編寫。 我感興趣的一個領域是直接內存管理的能力。 我正在努力學習如何使用它來優化我的代碼。 但是,我正在努力做到這一點,實際上看到任何真正的性能提升。 例如,以下是C#中的以下代碼:

unsafe static void Main(string[] args)
{
    int size = 300000;
    char[] numbers = new char[size];

    for (int i = 0; i < size; i++)
    {
        numbers[i] = '7';
    }

    DateTime start = DateTime.Now;

    fixed (char* c = &numbers[0])
    {
        for (int i = 0; i < 10000000; i++)
        {
            int number = myFunction(c, 100000);
        }
    }

    /*char[] c = numbers;  // commented out C# non-pointer version same 
          speed as C# pointer version
    {
        for (int i = 0; i < 10000000; i++)
        {
            int number = myFunction(c, 100000);
        }
    }*/

    TimeSpan timeSpan = DateTime.Now - start;
    Console.WriteLine(timeSpan.TotalMilliseconds.ToString());
    Console.ReadLine();
}

static int myFunction(ref char[] numbers, int size)
{
    return size * 100;
}

static int myFunction(char[] numbers, int size)
{
    return size * 100;
}

unsafe static int myFunction(char* numbers, int size)
{
    return size * 100;
}

無論我調用哪三種方法,我都獲得相同的執行速度。 我還在嘗試圍繞使用ref和使用指針之間的區別,除了這可能需要時間和練習。

然而,我不明白的是,我能夠在C ++中產生非常顯着的性能差異。 當我嘗試在C ++中使用相同的代碼時,我想到了以下內容:

/*int myFunction(std::string* numbers, int size)  // C++ pointer version commented 
     out is much faster than C++ non-pointer version
{
    return size * 100;
}*/

int myFunction(std::string numbers, int size) // value version
{
    return size * 100;
}

int _tmain(int argc, _TCHAR* argv[])
{
int size = 100000;
std::string numbers = "";
for (int i = 0; i < size; i++)
{
    numbers += "777";
}

clock_t start = clock();

for (int i = 0; i < 10000; i++)
{
    int number = myFunction(numbers, 100000);
}

clock_t timeSpan = clock() - start;

std::cout << timeSpan;
char c;
std::cin >> c;

return 0;
}

任何人都可以告訴我為什么我的C#代碼不會受益於我對引用或指針的使用? 我一直在網上讀東西,除了我被卡住了。

C#已經生成了指針而沒有你明確地聲明它們。 每個引用類型引用(如數字變量)實際上都是運行時的指針。 使用refout關鍵字傳遞的每個參數實際上都是運行時的指針。 數組參數的確切C等價物是char **,char *&C ++。 C#沒有區別。

所以你沒有看到速度上的任何差異,因為實際執行的代碼是相同的。

這不是它停止的地方,你從來沒有對數組做任何事情。 您調用的方法在運行時消失,就像在C或C ++編譯器中一樣,它將由優化器內聯 由於您不使用數組參數,因此您也沒有獲得任何代碼。

當您使用它們來實際處理內存時,指針對於加速程序非常有用。 您可以索引數組,並確保您永遠不會支付數組邊界檢查。 在許多情況下,您不會在正常使用情況下為此付費,如果抖動優化器知道索引始終是安全的,那么刪除檢查是相當明智的。 這是指針的不安全使用,你可以隨便亂寫到不屬於該數組的內存部分並以這種方式破壞GC堆。 用於對象引用或ref參數的指針永遠不會安全。

查看其中任何一個的唯一真正方法是查看生成的機器代碼。 Debug + Windows + Disassembly窗口。 重要的是,即使您調試代碼仍然需要優化,或者您無法看到優化​​。 確保運行Release版本並使用Tools + Options,Debugging,General,取消選中“在模塊加載時抑制JIT優化”選項。 需要熟悉機器代碼才能理解您所看到的內容。

問題是你沒有測量你認為你在測量的東西。 我可以閱讀你的代碼,並立即看到為什么你會得到這個結果或結果,這不僅僅是因為指針或指針。 還有許多其他因素在起作用,或者可能起作用。 各種評論反映了這一點。

對於它的價值,一個C ++調用比另一個慢得多的主要原因是因為慢速復制std :: string而快速復制沒有。 C#示例沒有類似它們之間的差異順序。

我的建議是,作為一個聰明但早期的程序員,你首先關注的是成為一個更好的程序員。 在您知道自己要實現的目標之前,不要擔心“優化”。

當您准備好真正理解這個問題時,您將不得不研究生成的代碼。 在C#的情況下,它是MSIL,以及它在特定平台上的JIT。 在C ++的情況下,英特爾為任何處理器操作代碼。 直到你知道MSIL和JIT和操作碼是什么,理解為什么你得到你所做的結果將很難解釋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM