2010-04-30 22 views
5

我想將自定義數據關聯到Type,並在運行時以極快的速度檢索數據。在.Net中將信息與'Type'對象關聯的最有效的性能方式是什麼?

這只是我的想象我的完美的世界,:

VAR MyInfo的= typeof運算(MyClass的).GetMyInformation();

這會很快......當然這不存在!如果是這樣,我不會問。和合)

這是使用定製的方式屬性:

變種MyInfo的= typeof運算(MyClass的).GetCustomAttribute( 「MyInformation」);

這是緩慢的,因爲它需要字符串 「MyInformation」

這是使用一個字典<類型的方式,MyInformation>的查找:

變種MyInfo的= myInformationDictionary [ typeof運算(MyClass的)];

這也很慢,因爲它仍然是'typeof(MyClass)'的查找。

我知道字典非常快,但這還不夠......它不如調用方法那麼快。它甚至不是相同的速度順序。

我不是說我希望它和方法調用一樣快。我想將信息與某種類型相關聯,並儘可能快地訪問它。我在問是否有更好的方法,或者事件是最好的方式。

任何想法??

謝謝!

編輯:

我以前所有的片斷提到typeof運算(MyClass的),是actualy變量...我不知道這是一個特定的MyClass的類型,它可以是任何類型:

類型myType = typeFromSomewhere;

即在這種情況下,MyClass只是說這個類是由我製作的,任何其他類型可能進入這種情況也是由我做的......所以它讀取

的typeof(一個我自己的班,我不知道巫婆一個是它,但它是我的肯定

編輯:結論

相關字典一些性能測試結果:

Dic.buckets | Dic.Count | Dic.Key | Ops(x17)/s | Avg.Time | Min.Time | Max.Time 
----------------------------------------------------------------------------- 
    17519 | 12467 | Type | 1051538 | 0.95μs | 0.86μs | 0.42ms 
     919 |  912 | Type |  814862 | 1.23μs | 1.14μs | 0.46ms 
    1162687 |  912 | Type | 1126382 | 0.89μs | 0.81μs | 0.33ms 
     919 |  912 | Type |  806992 | 1.24μs | 1.16μs | 0.21ms 
     17 |  17 | Type |  872485 | 1.15μs | 1.06μs | 0.31ms 
----------------------------------------------------------------------------- 
    36353 | 18160 | String |  227520 | 4.40μs | 3.98μs | 0.47ms 
     919 |  911 | String |  219159 | 4.57μs | 4.14μs | 0.29ms 
    1162687 |  911 | String |  236384 | 4.23μs | 3.82μs | 0.41ms 
     919 |  911 | String |  223042 | 4.49μs | 4.10μs | 0.43ms 
     17 |  17 | String |  229985 | 4.35μs | 3.94μs | 0.28ms 

接口C所有:

ops(x17)/s: 2896001 
Average: 0.35μs 
Min: 0.34μs 
Max: 1.20μs 

虛擬呼叫:

ops(x17)/s: 3115254 
Average: 0.32μs 
Min: 0.32μs 
Max: 0.65μs 

我看到,我有低估字典! =)

似乎Dictionary類型的任何東西比虛擬方法調用慢3倍到4倍。

這不是使用字符串字典的情況。那些比虛擬方法調用慢10倍到12倍。

所以我已經證實我錯了!

而且,我不會製造導彈!有人認爲這在評論波紋管=)

謝謝大家。

+3

的使用如果性能是問題的心臟請張貼硬性能要求通過解決方案將被判定(即每秒迭代的最小數量)。 – 2010-04-30 19:42:13

+2

我很想知道你寫的是什麼樣的超級程序,它的性能可靠,以至於字典被認爲太慢了。它必須像導彈或其他必須使用這些數據每秒鐘執行數百萬計算的東西。 – 2010-04-30 19:47:26

+0

您是否真的實現了它,並測量了屬性或字典「太慢」?除非你的字典包含大量的條目,否則我懷疑你會遇到性能問題。 – 2010-04-30 20:02:36

回答

5

Dictionary<Type,Object>適合我。

+0

確實!我錯了......我的前提是基於一些我懷着想念的舊測試。測試再次完成,併發布! – 2010-04-30 22:47:51

2

聲明你的類型的靜態屬性或方法。

class YourType 
{ 
    public static string GetMyInformation() 
    { 
    return "Some info on this type"; 
    } 
} 

然後你就可以在你的代碼中訪問數據如下

var myInfo = YourType.GetMyInformation(); 

還是我錯過了點?

+1

你錯過了我有一個Type變量的事實:var myType = typeof(something)...該類型不是一種固定類型。 – 2010-04-30 19:26:05

+0

@Miguel,對不起。我忽略了重要的細節... – 2010-04-30 19:57:06

+0

不是你的錯,我之前沒有提到過...但我現在更清楚了,我想! – 2010-04-30 21:01:58

5

這不僅僅是你的「完美世界」,它也是C#!您可以使用extension methods做正是你提出了哪些工作:

var myInfo = typeof(MyClass).GetMyInformation(); 

在靜態TypeUtilities類或如此,您將定義如下:

public static InfoType GetMyInformation(this Type type) 
{ 
    // Return InfoType object. 
} 

至於實際操作中返回的信息類型,這可以通過多種方式完成。一個簡單的if塊,一個靜態的Dictionary,給定類型的反射(使用屬性/方法),甚至其他。最好的方法非常依賴於上下文和特定的使用場景。

+0

但是,如何根據類型實現不同的行爲。我仍然需要查看查找表或其他內容。 – 2010-04-30 19:29:56

+2

根據場景的不同,字典或簡單的if語句或甚至一些反射可能是最好的。你能否詳細說明一下? – Noldorin 2010-04-30 19:34:54

+0

我已經解決了我的問題,只用一個簡單的4 buckests結構來緩存以前訪問的字典項目...現在它幾乎與方法調用一樣快,在大多數情況下......擴展方法並非如此,我只是在談論表現。謝謝! – 2010-04-30 22:58:05

0

爲System.Type寫入擴展方法,它將爲您執行所有此類操作。

2

嗯,你怎麼樣使用的Dictionary<string, MyInformation>字典:

你知道他們鍵入要定義已經在尋找,如果你使用的是typeof運算方法。相反,您可以聲明一個const string MY_CLASS_TYPE_NAME = "MyNamespace.MyClass"

這不是最漂亮的,但速度非常快,並且不會限制您的功能。

+0

我的測試表明,使用字典類型是最好的事情。 – 2010-04-30 22:49:07

2

爲什麼不使用GetCustomAttributes(typeof(MyInformationAttribute), false)

恕我直言,使用屬性是表達這種信息的語義正確的方式。只要確保使用密封的屬性類,就可以提高運行時性能。

雖然這並不困難,並且可能會更好地延遲加載或以某種方式緩存屬性實例。我通常在應用程序初始化時使用靜態字段執行此操作。

+0

但是,這對於BCL類型沒有用處。在這方面非常有限。 – Noldorin 2010-04-30 20:10:54

+0

我已經測試了所有使用反射的方式,並且它是一種與類型關聯信息的最佳方式(談論性能)。無論如何...感謝您的嘗試! – 2010-04-30 22:53:37

4

如果類型是靜態可用的,那麼可以考慮使用類似的東西,

public class Data<T, V> 
{ 
    public static V Info; 
} 

這是用來像,

Data<int, string>.Info = "A string associated with int"; 
Data<string, string>.Info = "A string associated with string"; 

,並像訪問,

Console.WriteLine(Data<int, string>.Info); 
Console.WriteLine(Data<string, string>.Info); 

這工作,因爲泛型類的靜態變量對於不同的泛型參數是唯一的。

如果類型不是靜態可用的,那麼您應該使用Dictionary<Type, V>,如您的問題中所述並由其他人推薦。

+0

非常有趣的是指出一種靜態的方式,但事實並非如此。字典鍵入的字典實際上是最好的方法...我錯了,它不是比虛擬電話慢一個數量級,它只是慢了3-4倍......對我來說就夠了。謝謝! – 2010-04-30 22:51:19

+2

我喜歡這種方法,實際上。雖然它很偷偷摸摸,但幾乎是一個黑客......利用稍微微妙的CLR功能來完成任務。 – Noldorin 2010-04-30 23:47:21

0

正如其他人所說的,你可能是微優化,但因爲我們都進入了它的精神,我也不能免俗:)

的.NET類型的類都可以歸結到它的運行時間如果你不需要反射,它可以比完整類型效率更高...

字典或任何你正在使用的是比剛剛運行的非常簡單的測試中的字典快大約20%。

typeof(object).RuntimeTypeHandle; 
// and 
instance.GetType().RuntimeTypeHandle; 

可以代替全類型實例

相關問題