[英]Using different API for different Windows versions efficiently
我面臨着在可用的情況下使用新的Windows運行時功能的需要,並且回歸到新的運行時功能不存在的情況。
代碼路徑對性能至關重要。 如果平台(Windows 8 / Windows Server 2012)提供它,我需要調用GetSystemTimePreciseAsFileTime
如果新版本不存在,則返回GetSystemTimeAsFileTime
。
我知道我可以使用LoadLibrary
和GetProcAddress
加載GetSystemTimePreciseAsFileTime
,如果失敗,則回退到GetSystemTimeAsFileTime
。 我擔心通過另一層間接性來調用某些東西作為性能的關鍵性能影響。
是否有任何內置機制來延遲加載符號,而不是整個DLL? 所以,我可以在啟動測試的Windows版本和調用使用功能GetSystemTimePreciseAsFileTime
上Win8的,否則調用使用了一個GetSystemTimeAsFileTime
,而不會導致整個可執行文件失敗,在舊版本的Windows鏈接錯誤?
或者我應該停止擔心並使用GetProcAddress
?
正如對問題的各種評論所說, GetProcAddress()
的成本很低。 通過函數指針調用函數的成本也接近於零。
但是,讓我們說我們正在超級批判地工作。 我們觀察到您要調用的兩個函數具有簽名
VOID WINAPI GetSystemTimePreciseAsFileTime(LPFILETIME lpSystemTimeAsFileTime);
void WINAPI GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime);
也就是說,它們具有幾乎相同的簽名; 唯一的區別是VOID
奇怪返回類型...... MSDN所說的只是一個擴展為void
的宏 ,所以它們完全相同。
這是什么意思? 這意味着您可以使用單個函數指針變量,在程序開始時初始化一次,如下所示:
// global scope
VOID (*WINAPI myGetSystemTime)(LPFILETIME);
// in your initalization code
FARPROC fp;
myGetSystemTime = GetSystemTimeAsFileTime;
if (/* LoadLibraryW(L"kernel32.dll") worked */) {
fp = GetProcAddress(/* library handle */, "GetSystemTimePreciseAsFileTime");
if (fp != NULL)
myGetSystemTime = (VOID (*WINAPI)(LPFILETIME)) fp;
}
// and don't worry about errors from LoadLibraryW() or GetProcAddress() since we want to use the fallback; you may log a warning if you so choose
然后你需要做的就是在需要選擇性地調用函數時調用(*myGetSystemTime)(&time)
。 沒有條件分支或不斷輪詢DLL,並且應該沒有可衡量的性能影響。
我認為andlabs的回答可能是正確的; 通過指針調用函數的性能損失不太可能很大。 另一方面,它確實需要額外的RAM往返(或者導致指針占用緩存中可能更好用的一行),所以它並不是絕對確定的。
如果分析表明您確實遇到了問題,請考慮將性能關鍵代碼放入DLL中。 有兩個版本的DLL,每個版本一個。 安裝應用程序后,將適當的版本放在適當的位置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.