从C5通用收集库小型集合是相对很慢 - 可以做什么吗? [英] Small sized collections from C5 Generic Collection Library are comparatively very slow - can anything be done?

查看:164
本文介绍了从C5通用收集库小型集合是相对很慢 - 可以做什么吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在C#中测试了C5集合,我喜欢他们的功能。对于大集合,性能似乎与通用对等物相当。然而对于小集合,它们显着更慢。我怀疑相对速度的急剧恶化来自C5集合执行的恒定时间操作。我知道的一个操作是发射事件。这可能是小集合的性能差的原因吗?这可能可以通过关闭一些功能来补救?这里的性能测试:

  //两个容器要测试。 'test'是一个十进制的包装。 
var arrayList = new C5.ArrayList< Test>();
var genericList = new System.Collections.Generic.List< Test>();

var toBeAdded = new List< Test>();
var watch = new Stopwatch();

//填充两个测试容器
for(int i = 10; i> 0; i--)
{
var test = new Test );
genericList.Add(test);
arrayList.Add(test);
}

//填充要插入到测试容器中的范围
for(int i = 5; i> 0; i--)
{
toBeAdded.Add(new Test(i + 0.5m));
}


//测试为两个容器添加一系列值和排序的速度
watch.Start();
genericList.AddRange(toBeAdded);
Console.WriteLine(为通用列表添加值:{0} ticks,watch.ElapsedTicks);
watch.Restart();
genericList.Sort();
Console.WriteLine(Sorting for generic list:{0} ticks,watch.ElapsedTicks);

watch.Restart();
arrayList.AddAll(toBeAdded);
Console.WriteLine(为C5 ArrayList添加值:{0} ticks,watch.ElapsedTicks);
watch.Restart();
arrayList.Sort();
Console.WriteLine(Sorting for C5 ArrayList:{0} ticks,watch.ElapsedTicks);

和测试类:

  class Test:IComparable 
{
private decimal _number;
内部测试(十进制aNumber)
{
_number = aNumber;
}
public int CompareTo(object obj)
{
var test =(Test)obj;
return _number.CompareTo(test._number);
}
}

输出为:



为通用列表添加值:56 ticks
排序通用列表:770 ticks
为C5添加值ArrayList:3575 ticks
Sorting for C5 ArrayList:4815 ticks

C5和测试都是Release版本。



编辑:上面的测试是在VS内部运行的。在VS外部运行的结果是:

 为通用列表添加值:54 ticks 
排序通用列表: 2135 ticks
为C5添加值ArrayList:5765 ticks
Sorting for C5 ArrayList:5198 ticks


$ b b

同样,插入的100x和排序的2x的速度比率在测试运行之间是一致的。



我的项目包括很多操纵小容器并且它们的性能是至关重要的。 C5容器的功能是伟大的,我很想使用它们,但目前不能为性能原因。



EDIT2:根据Iridium的回答,我在一个循环中执行了测试(将包含容器创建的整个逻辑放入循环,以排除任何编译器优化技巧),丢弃前两个结果和平均后续1000个结果。它们是:

 为通用列表添加值:1.09 ticks 
排序通用列表:14.07 ticks
为C5 ArrayList添加值ArrayList:1.92 ticks
Sorting for C5 ArrayList:13.69 ticks

C5插入速度降低了76%,排序与List类似。这对我的目的来说是够好的。我接受铱星的答案。不过,如果有人对慢插入有任何见解,请分享。感谢所有的帮助。

解决方案

我想知道这里如果你的结果有点误导,由于在第一次使用add / sort方法时装配加载/ JIT编译的开销,实际上(可能)C5的重新查看。



我使用C5 2.1.4596.30350重复了你的测试,但是,运行整个测试多次(不重新启动应用程序,以避免任何一次性开销)。结果似乎表明,第一次使用C5集合(与像JIT编译一样的开销一致)在后续使用中消失,这使得C5性能与通用集合的效率相同。 p>


I've recently been testing C5 collections in C# and I'm loving their functionality. For large collections the performance seems on par with the generic counterparts. For small collections however they are significantly slower. I suspect the dramatic deterioration in relative speed comes from constant time operations performed by C5 collections. One operation I know of is firing of events. Could this be the cause of poor performance for small collections? Can this perhaps be remedied by turning some functionality off? Here' the performance test:

//Two containers to be tested. 'Test' is a wrapper over decimal.
var arrayList = new C5.ArrayList<Test>();
var genericList = new System.Collections.Generic.List<Test>();

var toBeAdded = new List<Test>();
var watch = new Stopwatch();

//Fill both tested containers
for (int i = 10; i > 0; i--)
{
    var test = new Test(i);
    genericList.Add(test);
    arrayList.Add(test);
}

//Fill the container the range of which will be inserted to the tested containers
for (int i = 5; i > 0; i--)
{
    toBeAdded.Add(new Test(i+0.5m));
}


//Test the speed of adding a range of values and sorting for both containers
watch.Start();
genericList.AddRange(toBeAdded);
Console.WriteLine("Adding values for generic list: {0} ticks", watch.ElapsedTicks);
watch.Restart();
genericList.Sort();
Console.WriteLine("Sorting for generic list: {0} ticks", watch.ElapsedTicks);

watch.Restart();
arrayList.AddAll(toBeAdded);
Console.WriteLine("Adding values for C5 ArrayList: {0} ticks", watch.ElapsedTicks);
watch.Restart();
arrayList.Sort();
Console.WriteLine("Sorting for C5 ArrayList: {0} ticks", watch.ElapsedTicks);

and the Test class:

class Test : IComparable
{
    private decimal _number;
    internal Test(decimal aNumber)
    {
        _number = aNumber;
    }        
    public int CompareTo(object obj)
    {
        var test = (Test) obj;
        return _number.CompareTo(test._number);
    } 
}

The output is:

Adding values for generic list: 56 ticks
Sorting for generic list: 770 ticks
Adding values for C5 ArrayList: 3575 ticks
Sorting for C5 ArrayList: 4815 ticks

Both C5 and the test are Release builds. The ratio of speeds of around 60x for inserting and 6x for sorting is consistent between test runs.

EDIT: The above test was ran from within VS. The results for running outside of VS are:

Adding values for generic list: 54 ticks
Sorting for generic list: 2135 ticks
Adding values for C5 ArrayList: 5765 ticks
Sorting for C5 ArrayList: 5198 ticks

Again, the ratio of speeds of around 100x for inserting and 2x for sorting is consistent between test runs.

My project includes a lot of manipulating of small containers and their performance is paramount. The functionality of C5 containers is great and I'd love to use them, but at the moment can't for performance reasons. I'd appreciate any insight on the matter.

EDIT2: As per Iridium answer, I performed the test in a loop (putting the whole logic including the container creation into the the loop so as to exclude any compiler optimization tricks), discarded the first two results and averaged subsequent 1000 results. Here they are:

Adding values for generic list: 1.09 ticks
Sorting for generic list: 14.07 ticks
Adding values for C5 ArrayList: 1.92 ticks
Sorting for C5 ArrayList: 13.69 ticks

Now C5 insertion is 76% slower and sorting is on par with that of List. That's good enough for my purpose. I'm accepting Iridium's answer. Still, if anyone has any insight on the slower insertion, please share it. Thanks all for the help.

解决方案

I'm wondering here if your results are a little misleading, and that the differences you're seeing for C5 are in fact (possibly) due to the overhead of assembly loading/JIT compilation on the first use of the add/sort method. The generic collections not suffering from this as a result of the system assemblies having already been already loaded/NGen'ed.

I repeated your test using C5 2.1.4596.30350, but ran the whole test multiple times (without restarting the application so as to avoid any one-off overheads). The results seem to suggest that there is an time penalty on first use of C5 collections (consistent with a one-off overhead like JIT compilation) that disappears on subsequent uses, leaving C5 performance effectively the same as that of the generic collections.

这篇关于从C5通用收集库小型集合是相对很慢 - 可以做什么吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆