Citat:
Dejan Carić:
Dictionary jeste brži ali samo pod uslovom da
rec nikada nije null.
S obzirom da je string referentni tip, tako nešto je ipak moguće i tu
dict[rec]++; puca.
GroupBy je sporiji jer ima tu proveru ali zato sa njim možeš dohvatiti broj stringova koji su
null.
Zanimljivo, ispada da je Dictionary implementacija oko 2x sporija od one tvoje implementacije sa čistim linq query-em:
Code (csharp):
private void button1_Click
(object sender, EventArgs e
)
{
var wordlist
= new[] { "lorem",
"ipsum",
"dolor",
"sit",
"amet",
"null" };
var rnd
= new Random
(42);
var sample
= new List
<string>(10000);
for (var i
= 0; i
< 10000; i
++)
sample
.Add(wordlist
[rnd
.Next(wordlist
.Count())]);
var start
= DateTime
.Now.Ticks;
for(var i
= 0; i
< 1000; i
++)
{
var res
= (from x
in sample
group x by x
into g
let count
= g
.Count()
where count
> 1
orderby count descending
select new {Value
= g
.Key, Count
= count
}).ToList();
}
System.Diagnostics.Debug.Print(new TimeSpan
(DateTime
.Now.Ticks - start
).ToString());
}
private void button2_Click
(object sender, EventArgs e
)
{
var wordlist
= new[] { "lorem",
"ipsum",
"dolor",
"sit",
"amet",
"null" };
var rnd
= new Random
(42);
var sample
= new List
<string>(10000);
for (var i
= 0; i
< 10000; i
++)
sample
.Add(wordlist
[rnd
.Next(wordlist
.Count())]);
var start
= DateTime
.Now.Ticks;
for (var i
= 0; i
< 1000; i
++)
{
var res
= new Dictionary
<string,
int>();
foreach (var s
in sample
)
if (res
.ContainsKey(s
))
res
[s
]++;
else
res
.Add(s,
1);
}
System.Diagnostics.Debug.Print(new TimeSpan
(DateTime
.Now.Ticks - start
).ToString());
}
Rezultat (i7-930):
00:00:00.8290474 -- Linq group
00:00:01.3500773 -- Dictionary
Nema
null vrednosti, da bi bilo "fer". Rezultat Dictionary implementacije još uključuje i rezultate sa jednim ponavljanjem, znači trebao bi i još jedan filter na kraju.
EDIT:
Ruku na srce Dictionary implementacija može da se malo bolje napiše, da se izbegne trodupli lookup, jer indekser++ u stvari radi set(get()+1) plus jedan za ContainsKey():
Code (csharp):
int count;
foreach (var s in sample)
if (res.TryGetValue(s, out count))
res[s] = count + 1;
else
res.Add(s, 1);
Ovo se izvršava za 00:00:00.9590548, što je dosta bolje mada još uvek sporije od linq implementacije.
[Ovu poruku je menjao Boris B. dana 26.11.2011. u 02:11 GMT+1]
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.