ArraySegment - 选举的实际段C# [英] ArraySegment - Returning the actual segment C#

查看:101
本文介绍了ArraySegment - 选举的实际段C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在就如何恢复它基本上是ArraySegment偏移和计数方面举行的段东张西望。虽然ArraySegment保持完整和原始阵列,它只是与事实到段的任何变化都反映到原始限定它。的问题,或者说与ArraySegment的限制是,它本身并不返回段作为一个整体,我必须遍历的值。什么是返回段作为一个整体的最佳方式?

I have been looking around on ways to return the segment which is basically held by ArraySegment in terms of offset and count. Although ArraySegment holds the complete and original array, it just delimits it with the fact that any changes to the segment are reflected into the original. The problem or say the limitation with ArraySegment is that it will not return the segment itself as a whole and I have to traverse the values. What would be the best way to return the segment as a whole?

 byte[] input = new byte[5]{1,2,3,4,5};
 ArraySegment<byte> delimited = new ArraySegment<byte>(input,0,2);
 byte[] segment = HERE I NEED SOMETHING THAT WILL RETURN THE SEGMENT i.e. [0,1,2]

最重要的一点,段不能是复印件,但应参照原始数组。如果细分的任何变化都做了,所以一定要反映原始数组中

The most important point, segment must not be a copy but should refer to the original array. If any changes to segment are done, they must be reflected in the original array.

任何提示是非常AP preciated,谢谢!

Any tips are highly appreciated, thanks!

转让基准:从托马斯并的digEmAll

好吧,我跑了反对从digEmAll和托马斯code一些基准,并让我吃惊的code是压倒性的速度更快。正是我一直在拼命地寻找。下面是结果。

Ok, I ran some benchmarks against the code from digEmAll and Thomas, and to my surprise the code is overwhelmingly faster. Just what I was desperately looking for. Here are the results.

Construct             Size    Elements assigned    Iterations       Time
_______________________________________________________________________________

ArraySegmentWrapper   1500        1500              1000000       396.3 ms
Array.Copy            1500        1500              1000000       4389.04 ms

正如你可以看到惊人的差异,这是非常清楚的,我认为我应该使用code表示ArraySegment。下面是标杆code。请注意,这可能会有点
作为偏人会认为为什么新已经放了循环内。我只是想重现我现在手头上的决心,它尽可能的情况下不动,大部分的code的。这只是让我很快乐!

As you can see the whopping difference, it is very clear to me that I shall be using the code for ArraySegment. Below is the benchmarking code. Please note that this might be a bit biased as people would argue why "new" has been put inside a loop. I am just trying to reproduce the situation I currently have at hand at resolve it as much as possible without moving much of the code. This just made my day!

namespace ArraySegmentWrapped
{
    class Program
    {

        public static Stopwatch stopWatch = new Stopwatch();
        public static TimeSpan span = new TimeSpan();
        public static double totalTime = 0.0;
        public static int iterations = 1000000;

        static void Main(string[] args)
        {
            int size = 1500;
            int startIndex = 0;
            int endIndex = 1499;
            byte[] array1 = new byte[size];
            byte[] array2 = null;

            for (int index = startIndex; index < size; index++)
            {
                array1[index] = (byte)index;
            }

            ArraySegmentWrapper<byte> arraySeg;

            for (int index = 0; index < iterations; index++)
            {
                stopWatch.Start();
                arraySeg = new ArraySegmentWrapper<byte>(array1, startIndex, endIndex);            
                stopWatch.Stop();
                totalTime += stopWatch.Elapsed.TotalMilliseconds;
            }

            Console.WriteLine("ArraySegment:{0:F6}", totalTime / iterations);
            stopWatch.Reset();
            totalTime = 0.0;

            for (int index = 0; index < iterations; index++)
            {
                stopWatch.Start();
                array2 = new byte[endIndex - startIndex + 1];
                Array.Copy(array1, startIndex, array2, 0, endIndex);
                stopWatch.Stop();
                totalTime += stopWatch.Elapsed.TotalMilliseconds;
            }
            Console.WriteLine("Array.Copy:{0:F6}", totalTime / iterations);                        


        }
    }
// Code for ArraySegmentWrapper goes here    

}

使用基准(更新)
 什么托马斯曾指出有关标准和说,获得简单数组会比较快ArraySegment如此之后,他是完全正确的。但随着digEmAll指出,我应该在Release模式下测试(在调试模式下测试的老错误道歉的话),我离开了code几乎相同,上述(迭代由两个零减少 - 不能等待很长的时间输出来,对不起)和一些修改访问相同数量的元素,下面是我得到了什么。

ACCESS BENCHMARKS (Updated) So after what Thomas had pointed about the benchmarks and said that access to simple arrays would be faster as compared to ArraySegment, he was totally right. But with digEmAll pointing out that I should test in Release mode (sorry for the old mistake of testing in debug mode), I left the code almost the same as above(iterations reduced by two zeros - could not wait very long for the output to come, sorry) and some modifications to access the same number of elements, Below is what I got.

Construct             Size    Elements accessed    Iterations       Time
_______________________________________________________________________________

ArraySegmentWrapper   1500        1500              1000000       5268.3 ms
Array.Copy            1500        1500              1000000       4812.4 ms

结论是,虽然assingment是非常快的,访问都通过ArraySegments缓慢。

Concluded that although assingment is very fast, access is slow via ArraySegments.

推荐答案

从开始<一href=\"http://stackoverflow.com/questions/5756692/arraysegment-returning-the-actual-segment-c/5756714#5756714\">Thomas Levesque的的建议我已经建立了一个简单的 ArraySegmentWrapper&LT; T&GT; 类以这种方式使用:

Starting from Thomas Levesque's suggestion I've built a simple ArraySegmentWrapper<T> class to use in this way:

static void Main(string[] args)
{
    int[] arr = new int[10];
    for (int i = 0; i < arr.Length; i++)
        arr[i] = i;

    // arr = 0,1,2,3,4,5,6,7,8,9

    var segment = new ArraySegmentWrapper<int>(arr, 2, 7);
    segment[0] = -1;
    segment[6] = -1;
    // now arr = 0,1,-1,3,4,5,6,7,-1,9


    // this prints: -1,3,4,5,6,7,-1
    foreach (var el in segment)
        Console.WriteLine(el);
}

实施

public class ArraySegmentWrapper<T> : IList<T>
{
    private readonly ArraySegment<T> segment;

    public ArraySegmentWrapper(ArraySegment<T> segment)
    {
        this.segment = segment;
    }

    public ArraySegmentWrapper(T[] array, int offset, int count)
        : this(new ArraySegment<T>(array, offset, count))
    {
    }

    public int IndexOf(T item)
    {
        for (int i = segment.Offset; i < segment.Offset + segment.Count; i++)
            if (Equals(segment.Array[i], item))
                return i;
        return -1;
    }

    public void Insert(int index, T item)
    {
        throw new NotSupportedException();
    }

    public void RemoveAt(int index)
    {
        throw new NotSupportedException();
    }

    public T this[int index]
    {
        get
        {
            if (index >= this.Count)
                throw new IndexOutOfRangeException();
            return this.segment.Array[index + this.segment.Offset];
        }
        set
        {
            if (index >= this.Count)
                throw new IndexOutOfRangeException();
            this.segment.Array[index + this.segment.Offset] = value;
        }
    }

    public void Add(T item)
    {
        throw new NotSupportedException();
    }

    public void Clear()
    {
        throw new NotSupportedException();
    }

    public bool Contains(T item)
    {
        return this.IndexOf(item) != -1;
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        for (int i = segment.Offset; i < segment.Offset + segment.Count; i++)
        {
            array[arrayIndex] = segment.Array[i];
            arrayIndex++;
        }
    }

    public int Count
    {
        get { return this.segment.Count; }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    public bool Remove(T item)
    {
        throw new NotSupportedException();
    }

    public IEnumerator<T> GetEnumerator()
    {
        for (int i = segment.Offset; i < segment.Offset + segment.Count; i++)
            yield return segment.Array[i];
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

这篇关于ArraySegment - 选举的实际段C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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