C5 通用集合库中的小型集合相对来说非常慢 - 有什么办法吗? [英] Small sized collections from C5 Generic Collection Library are comparatively very slow - can anything be done?

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

问题描述

我最近一直在用 C# 测试 C5 集合,我很喜欢它们的功能.对于大型集合,性能似乎与通用对应物相当.但是,对于小型集合,它们的速度要慢得多.我怀疑相对速度的急剧下降来自 C5 集合执行的恒定时间操作.我知道的一项操作是触发事件.这可能是小型集合性能不佳的原因吗?可以通过关闭某些功能来解决这个问题吗?这里是性能测试:

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);

和测试类:

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);
    } 
}

输出是:

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

C5 和测试都是发布版本.60x 左右的插入速度和 6x 排序速度的比率在测试运行之间是一致的.

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.

上面的测试是在 VS 中运行的.在VS外运行的结果是:

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

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

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

我的项目包括对小型容器的大量操作,它们的性能至关重要.C5 容器的功能很棒,我很想使用它们,但目前由于性能原因不能使用.如有任何关于此事的见解,我将不胜感激.

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.

根据 Iridium 的回答,我在循环中执行了测试(将包括容器创建在内的整个逻辑放入循环中,以排除任何编译器优化技巧),丢弃前两个结果并平均随后的 1000 个结果.他们在这里:

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

现在 C5 插入速度慢了 76%,排序与 List 相同.这对我的目的来说已经足够了.我接受铱星的回答.不过,如果有人对较慢的插入有任何见解,请分享.谢谢大家的帮助.

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.

推荐答案

我想知道你的结果是否有点误导,你看到的 C5 差异实际上(可能)是由于开销首次使用 add/sort 方法时的程序集加载/JIT 编译.由于系统程序集已经加载/NGen'ed,通用集合不会受到此影响.

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.

我使用 C5 2.1.4596.30350 重复了您的测试,但多次运行整个测试(没有重新启动应用程序以避免任何一次性开销).结果似乎表明,第一次使用 C5 集合时存在时间损失(与 JIT 编译等一次性开销一致),在后续使用时会消失,从而使 C5 性能实际上与通用集合的性能相同.

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天全站免登陆