2010-03-02 80 views
3

我正在開發一個GUI框架,我希望所有的元素都可以通過最多8個字符的ASCII字符串來標識(否則7就可以)。快速64位比較

每當一個事件被觸發(有些只是點擊,但有些是連續的),該框架將回調到編號,並將其值的客戶端代碼。我可以使用實際的字符串和strcmp(),但我想這是非常快的(對於移動設備),所以我想用char常量(例如int id ='BTN1';),所以你會做一個int比較來測試id。但是,4個字符不夠可讀。

我嘗試了一個實驗,一些喜歡 - 長整型ID = L'ABCDEFG「;

...但它看起來好像燒焦常量只能容納4個字符,而唯一讓long int類型的字符常量給你是你4個字符的兩倍寬的能力,不具備兩倍的字符。我在這裏錯過了什麼嗎?

我想很容易讓編寫客戶端代碼的人。 gui存儲在xml中,所以id從字符串中加載,但是會在客戶端代碼中寫入常量來比較這些常量。

因此,長期和短期的是,我正在尋找一個跨平臺的方式來做到快速7-8字符比較,任何想法?

+2

多少萬每秒你做比較?不要爲它出汗,它的速度足夠快。 – 2010-03-02 15:45:30

+0

如果你的目標是給你的組件一個命名方案,不要使用long-char對ascii的支持。 – 2010-03-02 15:47:50

+0

這可能不便攜。根據C++標準,多字符文字(多個字符之間的字符)的值是實現定義的。檢查你的實現的文檔,看看它是否在做你想做的事情,並檢查所有可用於實現的實現,看看它們是否都做同樣的事情。 – 2010-03-02 16:38:14

回答

4

您確定這不是過早優化嗎?你有沒有分析另一個純粹來自字符串比較的緩慢的GUI框架?爲什麼你確定字符串比較太慢?當然你不是在做多串比較。此外,考慮strcmp應該有一個接近最佳的實現,可能會寫在爲您正在編譯的CPU量身定製的彙編中。

反正其他框架只是使用命名整數,例如:

static const int MY_BUTTON_ID = 1; 

你可以考慮代替,避免了串問題完全。或者,您可以簡單地編寫一個幫助函數將const char [9]轉換爲64位整數。這應該接受一個以空字符結尾的字符串「像這樣」,最多8個字符(假設你打算拋棄空字符)。然後你的程序傳遞64位整數,但程序員正在處理字符串。

編輯:這裏有一個快速的函數,把一個字符串中的數字:

__int64 makeid(const char* str) 
{ 
    __int64 ret = 0; 
    strncpy((char*)&ret, str, sizeof(__int64)); 
    return ret; 
} 
+0

我見過很多gui框架使用int ids,但由於我的框架是基於界面構建器的,編碼器必須將數字複製到他們的代碼中(不雅),或者界面構建器必須生成一個頭文件爲每個元素定義,這將不適用於框架的一些應用 我認爲你是完全正確的,我沒有做很多比較,所以我會堅持使用字符串。我敢肯定在我的代碼中會有更大的瓶頸!謝謝! – mazbox 2010-03-02 16:53:14

+0

爲什麼選擇這個答案如果你要堅持使用字符串,還有其他人花時間回答你的具體問題? ? – 2010-03-02 16:55:23

+0

也許你沒有得到我答案的最後部分,所以我編輯了一個函數來顯示。如果你調用makeid(「我的id」),你會得到一個__int64,並將字符串複製到它。這使您可以使用程序員輸入字符串的便利性進行整數比較。注意它忽略了8號以後的任何字符。 – AshleysBrain 2010-03-02 22:42:45

1

輕鬆搞定預軋組件

binary search tree爲贏 - 你從集和地圖的最STL實現獲得red-black樹,所以你可能要考慮這一點。

Intrusive versions當您將容器節點移動很多時(通常情況下),STL容器執行的效果會更好 - 但是它們有相當多的注意事項。

具體意見 - 第一替代

如果我是你,我會堅持到64位整數類型,並在介入式容器將其捆綁,並使用升壓提供的庫。然而,如果你對這類事情還不熟悉,那麼使用stl :: map它在概念上更容易掌握,並且泄漏資源的可能性較小,因爲這裏有更多關於這些類型的容器和最佳實踐的文獻和指南。

替代2

你正在試圖解決我相信這個問題:是有它映射到手柄一個全球性的命名方案。您可以創建名稱映射到手柄,讓您可以使用的名稱檢索句柄:

// WidgetHandle is a polymorphic base class (i.e., it has a virtual method), 
// and foo::Luv implement WidgetHandle's interface (public inheritance) 
foo::WidgetHandle * LuvComponent = 
      Factory.CreateComponent<foo::Luv>("meLuvYouLongTime"); 
.... 

.... // in different function 
foo::WidgetHandle * LuvComponent = 
      Factory.RetrieveComponent<foo::Luv>("meLuvYouLongTime"); 

方案2是IPC一個常見的成語,你在一個過程中創建一個IPC型說的管道,你可以請求內核以名稱檢索管道的另一端。

+0

感謝您的回答。我想我一直在尋找最少的LOC版本,對於程序員來說最簡單的方法就是儘可能快地嘗試。我已經對它的組件檢索部分進行了排序,它只是確定事件來自哪個組件。 – mazbox 2010-03-04 11:44:15

1

string interning概念可以針對此問題是有用的,轉動串比較入指針進行比較。

+0

我喜歡只比較指針的想法,但我試圖得到一個解決方案,對於編碼者的角度來看也是最優的(也許我不能擁有兩全其美),例如(id = SOME_MACRO('myButton')){ doSomethingWith(value); (id == SOME_MACRO('mySlider')){ doSomethingElse(value); } } 在這樣的代碼中,文字'myButton'和'mySlider'的代碼很少,程序員編寫的代碼更少。 也許我可以把SOME_MACRO()變成一個哈希函數... – mazbox 2010-03-02 15:57:44

4

一種可能性是定義你的ID作爲一個64位整數的工會和8個字符的字符串:

union ID { 
    Int64 id;  // Assuming Int64 is an appropriate typedef somewhere 
    char name[8]; 
}; 

現在你可以做這樣的事情:

ID id; 
strncpy(id.name, "Button1", 8); 
if (anotherId.id == id.id) ... 
+0

聰明...(15個字符) – 2010-03-04 12:01:49

+0

我在過去做過同樣的事情,它運行良好。 – 2015-04-03 18:44:40

0

我見區分代碼中易於閱讀的標識符和傳遞的表示。

您可以使用枚舉類型(或常量的大頭文件)來表示標識符嗎?那麼枚舉類型的名稱就可以像你期望的那樣長和有意義,並且仍然適合於(我猜測)幾個字節。

0

在C++ 0x中,你就可以使用user-defined string literals,所以你可以添加喜歡7chars..id"7chars.."id東西:

template <char...> constexpr unsigned long long operator ""id(); 
constexpr unsigned long long operator ""id(const char *, size_t); 

雖然我不知道你可以使用constexpr的第二個。