用于C#的类似V8的哈希表?

我正在编程一个公寓和房屋租赁网站。 由于不会有超过10'000个物业出租,把所有物品都存入记忆体是没有问题的。 现在,当用户想要search特定的一个,他可以定义非常多的价格,房间,自动扶梯等filter。

每个属性都有一组非常不同的属性。 一个属性可能具有另一个属性不具有的属性。 所以,在C#中创build一个具有所有属性的类,而仅使用其中一些属性对我来说不是一个好主意。 我决定使用一个字典来代替。

稍后的一些基准testing中,我发现,Dictionary作为一个类访问属性的速度要慢大约40倍。 我也做了一个node.js的基准,它只是用对象作为字典。 这是非常有趣的,因为node.js中完全相同的程序比使用本地类的C#示例执行得更好。

其实我得到了以下结果:

C#字典:〜820ms C#类:〜26ms Node.js对象:〜24ms

每个基准都按照相同的标准search1000万个物体。

我知道,由于Google的V8引擎,Node.js版本非常快。 你知道是否有一个C#类使用与V8引擎类似的技术,并获得几乎相同的性能?

C#字典基准

namespace Test { class Program { static void Main(string[] args) { PropertyList p = new PropertyList(); long startTime = DateTime.Now.Ticks; for (int i = 0; i < 100; i++) { p.Search(); } Console.WriteLine((DateTime.Now.Ticks - startTime) / 10000); } } class PropertyList { List<Property> properties = new List<Property>(); public PropertyList() { for (int i = 0; i < 10000; i++) { Property p = new Property(); p["Strasse"] = "Oberdorfstrasse"; p["StrassenNr"] = 6; p["Plz"] = 6277; p["Ort"] = "Lieli"; p["Preis"] = 600; p["Fläche"] = 70; p["Zimmer"] = 2; p["Lift"] = true; p["Verfügbarkeit"] = 7; p["Keller"] = false; p["Neubau"] = true; p["ÖV"] = false; properties.Add(p); } } public void Search() { int found = 0; for (int i = 0; i < properties.Count; i++) { Property p = properties[i]; if ((string)p["Strasse"] == "Oberdorfstrasse" && (int)p["StrassenNr"] == 6 && (int)p["Plz"] == 6277 && (string)p["Ort"] == "Lieli" && (int)p["Preis"] >= 500 && (int)p["Preis"] <= 1000 && (int)p["Fläche"] >= 10 && (int)p["Fläche"] <= 200 && (int)p["Zimmer"] == 2 && (bool)p["Lift"] == true && (int)p["Verfügbarkeit"] >= 2 && (int)p["Verfügbarkeit"] <= 8 && (bool)p["Keller"] == false && (bool)p["Neubau"] == true && (bool)p["ÖV"] == true ) { found++; } } } } class Property { private Dictionary<string, object> values = new Dictionary<string, object>(); public object this[string key] { get { return values[key]; } set { values[key] = value; } } } } 

C#级基准

 namespace Test { class Program { static void Main(string[] args) { SpecificPropertyList p2 = new SpecificPropertyList(); long startTime2 = DateTime.Now.Ticks; for (int i = 0; i < 100; i++) { p2.Search(); } Console.WriteLine((DateTime.Now.Ticks - startTime2) / 10000); } } class SpecificPropertyList { List<SpecificProperty> properties = new List<SpecificProperty>(); public SpecificPropertyList() { for (int i = 0; i < 10000; i++) { SpecificProperty p = new SpecificProperty(); p.Strasse = "Oberdorfstrasse"; p.StrassenNr = 6; p.Plz = 6277; p.Ort = "Lieli"; p.Preis = 600; p.Fläche = 70; p.Zimmer = 2; p.Lift = true; p.Verfügbarkeit = 7; p.Keller = false; p.Neubau = true; p.ÖV = false; properties.Add(p); } } public void Search() { int found = 0; for (int i = 0; i < properties.Count; i++) { SpecificProperty p = properties[i]; if (p.Strasse == "Oberdorfstrasse" && p.StrassenNr == 6 && p.Plz == 6277 && p.Ort == "Lieli" && p.Preis >= 500 && p.Preis <= 1000 && p.Fläche >= 10 && p.Fläche <= 200 && p.Zimmer == 2 && p.Lift == true && p.Verfügbarkeit >= 2 && p.Verfügbarkeit <= 8 && p.Keller == false && p.Neubau == true && p.ÖV == true ) { found++; } } } } class SpecificProperty { public string Strasse; public int StrassenNr; public int Plz; public string Ort; public int Preis; public int Fläche; public int Zimmer; public bool Lift; public int Verfügbarkeit; public bool Keller; public bool Neubau; public bool ÖV; } } 

Node.js基准

 var properties = []; for(var i = 0; i < 10000; i++){ var p = { Strasse:"Oberdorfstrasse", StrassenNr:6, Plz:6277, Ort:"Lieli", Preis:600, Fläche:70, Zimmer:2, Lift:true, Verfügbarkeit:7, Keller:false, Neubau:true, ÖV:false }; properties.push(p); } function search(){ var found = 0; for(var i = 0; i < properties.length; i++){ var p = properties[i]; if(p.Strasse == "Oberdorfstrasse" && p.StrassenNr == 6 && p.Plz == 6277 && p.Ort == "Lieli" && p.Preis >= 500 && p.Preis <= 1000 && p.Fläche>= 10 && p.Fläche <= 100 && p.Zimmer == 2 && p.Verfügbarkeit >= 2 && p.Verfügbarkeit <= 8 && p.Keller == false && p.Neubau == true && p.ÖV == false ){ found++; } } } var startTime = new Date().getTime(); for(var i = 0; i < 100; i++){ search(); } console.log(new Date().getTime()-startTime); 

好吧,C#的速度较慢的原因是V8正好为这种情况进行了优化(大量字典具有完全相同的成员)。

你有点滥用C#在这里。 而不是字典,只要使用一个普通的类与自动属性。 C#将比V8更快,因为你正在发挥自己的实力而不是弱点。

这就是为什么你的“特定对象”基准是最快的。