2015-08-08 65 views
-1

我有一個循環計數爲10000000000的代碼,在該循環中,我使用條件運算符(如果有)進行一些計算。大概需要5分鐘才能達到這個數字。所以,我的問題是,我可以通過創建一個DLL並調用該函數來執行計算並將值返回給主程序來縮短所需的時間嗎?它會在計算所需的時間上產生差異嗎?此外,它是否會提高該計劃的整體效率?DLL在多大程度上加速了代碼中的計算,如循環等

+2

你爲什麼會認爲DLL會對性能有任何影響?函數是一個函數,它的位置沒有區別。 – MrEricSir

+1

也許['Parallel.ForEach'](https://msdn.microsoft.com/en-us/library/dd460720(v = vs.110).aspx)可以提供幫助。但是沒有看到代碼就很難說。 – OneFineDay

+0

謝謝OneFineDay,:)。我要去試試:) – LastOne

回答

0

通過「dll」,我假設你的意思是從被管理的.net代碼轉到未被管理的「本地」編譯代碼。是的這種方法可以幫助。

這很大程度上取決於。請記住,循環代碼的速度在典型的i3上可能只有25秒(這是循環到100億的成本和開銷,但沒有別的辦法)。

我假定你去了項目,然後編譯。在該屏幕上選擇高級編譯。你想檢查刪除整數溢出檢查。確保你的循環變量是整數速度。

此時,什麼都不做的「基礎」循環將從大約20秒降到大約6秒。

所以這就是基本的循環速度 - 現在歸結到我們在循環中做的事情。

在這一點上.net是否有一個JIT(即時編譯器)。這意味着您的源代碼將轉到「CLR」代碼,然後在代碼中將代碼編譯爲本機x86彙編代碼。所以這個「確實」將源代碼降低到真正的機器代碼級別。然而,JIT當然不是那麼高效,也不會花費時間來優化代碼,因爲JIT必須在「飛行」中工作,而不必注意它。因此,一個C++(或VB6,當本地編譯時運行速度與C++一樣快)可以運行得更快,但問題是多少?

優化的編譯器可能會得到另一個兩倍速度實際循環代碼等

然而,在這兩種情況下(使用.NET託管代碼,或編譯爲本地代碼英特爾碼),他們倆是LIKELY調用SAME例程來做數學運算!換句話說,如果80%的代碼花費在執行數學運算的「庫」代碼中,那麼從C++調用這樣的代碼或從.net調用這樣的代碼將會產生非常小的差別,因爲BULK該工作花費在相同的系統代碼中!

上述概念與您的應用模式相比確實是「主管」模式。

換句話說,在代碼中花費的時間與使用系統「庫」代碼所花費的時間相比,意味着在主管代碼中發生了大量的起伏提升。這意味着從.net跳轉到本地C++/vb6 dll的性能不會產生太大的影響。

所以我會首先確保你的代碼中的循環和數組索引引用是整數類型。上面的提示可能會讓你「接近」使用.dll。更糟的是往往是「洗牌」數據兩次,並從該external.dll子將花費你比在處理方保存的時間更多的時間。

如果你的程序正在做數據庫或文件I/O,那麼所有的投注都關閉,因爲這是非常不同的問題。

所以我會首先測試/嘗試你的應用程序與[x]刪除整數溢出檢查關閉。並且確保在測試期間使用ctrl-F5代替F5來在沒有調試的情況下運行代碼。在調試模式下,上面的溢出檢查和選項不會顯示增加的速度。

所以很難說 - 它實際上取決於你在做什麼(主管代碼)與僅僅在數組中移動值相關的數學(特別是浮動調用)。如果更多的代碼正在移動,那麼我建議上面的整數優化,而去一個.dll可能無濟於事。

+0

謝謝阿爾貝詳細的答案,我試着禁用整數溢出檢查等,並運行CTRL-F5。它肯定可以將速度提高30%左右,但是在構建項目後速度不會提高,獨立的exe文件不會產生相同的速度。我不知道爲什麼它不會產生相同的結果。 – LastOne

+0

您的結果應用程序應至少和ctrlF5一樣運行。這裏不對勁。我會創建一個非調試版本。我也會嘗試強制應用程序到x32(x86),看看它是否運行得更好。也可以嘗試x64。 –

0

難道你不能利用「Parallel.ForEach」並將這個巨大的循環拆分成幾個相等的部分嗎?

或嘗試使用一些Backgroundworkers或甚至線程(超過1 !!)來實現最佳CPU性能並嘗試減少使用時間。

+0

謝謝大衛BS,:)。我要去試試:) – LastOne

+0

不客氣。如果您對此有疑問,請告訴我。擁抱! –