Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何提高二维阵列的性能?_C#_Performance_Optimization_Wrapper - Fatal编程技术网

C# 如何提高二维阵列的性能?

C# 如何提高二维阵列的性能?,c#,performance,optimization,wrapper,C#,Performance,Optimization,Wrapper,我试着用。但是,它不支持int。因此,我必须为锯齿状2d数组创建一个包装器 我知道参差不齐的数组已经存在 根据我的测试结果,裸锯齿阵列是最快的。 但是,就包装器而言,2d包装器相对更快 现在,我有两个问题: 为什么锯齿形包装比2d包装慢 有可能使包装器运行得和裸包装器一样快吗 源代码 测试代码 位图bmpImage=DataConverter2d.ReadGray(“image.jpg”); int[][]intNakedJagged=DataConverter2d.ToInteger(bmp

我试着用。但是,它不支持
int
。因此,我必须为锯齿状2d数组创建一个包装器

我知道参差不齐的数组已经存在

根据我的测试结果,裸锯齿阵列是最快的。 但是,就包装器而言,2d包装器相对更快

现在,我有两个问题:

  • 为什么锯齿形包装比2d包装慢
  • 有可能使包装器运行得和裸包装器一样快吗
  • 源代码

    测试代码

    位图bmpImage=DataConverter2d.ReadGray(“image.jpg”); int[][]intNakedJagged=DataConverter2d.ToInteger(bmpImage); int[,]intNaked2d=JagMatrix.To2d(intNakedJagged); JagMatrix IntjaggedRapper=新的JagMatrix(intNakedJagged); DenMatrix intDenWrapper=新的DenMatrix(intNaked2d); 矩阵int2dWrapper=新矩阵(intNaked2d); 秒表sw1=新秒表(); sw1.Start(); double[,]dImage=DataConverter2d.ToDouble(intNaked2d); sw1.Stop(); WriteLine(“裸2d数组:”+sw1.elapsedmillisons.ToString()+“毫秒”,“已用时间”); 秒表sw2=新秒表(); sw2.Start(); double[]dImageJagged=DataConverter2d.ToDouble(intNakedJagged); sw2.Stop(); WriteLine(“裸锯齿数组:”+sw2.elapsedmillesons.ToString()+“毫秒”,“已用时间”); 秒表sw3=新秒表(); sw3.Start(); JagMatrix djagaray2d=DataConverter2d.ToDouble(intJaggedWrapper); sw3.Stop(); WriteLine(“锯齿形包装器:+sw3.elapsedmillesons.ToString()+“毫秒”,“已用时间”); 秒表sw4=新秒表(); sw4.Start(); DenMatrix dDenArray2d=DataConverter2d.ToDouble(intDenWrapper); sw4.Stop(); WriteLine(“密集包装器:+sw4.elapsedmillisons.ToString()+”毫秒“,”经过的时间”); 秒表sw5=新秒表(); sw5.Start(); 矩阵dArray2d=DataConverter2d.ToDouble(int2dWrapper); sw5.Stop(); WriteLine(“2d包装器:+sw5.elapsedmillisons.ToString()+“毫秒”,“已用时间”); Console.ReadKey(); 二维矩阵

    公共类矩阵:IDisposable,其中T:struct,IComparable
    {
    私人T[,]uuu2d;
    公共整数宽度{get;set;}
    公共整数高度{get;set;}
    公共图书馆是空的
    {
    得到
    {
    if(_array2d==null)返回true;
    否则返回false;
    }
    }
    公共矩阵(){}
    公共矩阵(T[,]数据)
    {
    本.集(数据);
    }
    公共矩阵(整数行,整数列)
    {
    宽度=行;
    高度=cols;
    __array2d=新T[宽度、高度];
    }
    公共T获取(整数x,整数y)
    {
    if(uuu array2d==null)
    {
    抛出新异常(“数组为空”);
    }
    如果(x<宽度和y<高度)
    {
    if(_array2d!=null)
    {
    返回数组2d[x,y];
    }
    其他的
    {
    抛出新异常(“数组为空”);
    }
    }
    其他的
    {
    string message=string.Empty;
    如果(x>=宽度)消息=“x值超过宽度”;
    如果(y>=高度)消息+=“y值超过高度”;
    message+=“在Array2d.Get(x,y)中”;
    抛出新异常(消息);
    }
    }
    公共无效集(整数x,整数y,T val)
    {
    if(uuu array2d==null)
    {
    __array2d=新T[宽度、高度];
    }
    其他的
    {
    如果(宽度!=\uuuuArray2D.GetLength(0))
    {
    __array2d=null;
    __array2d=新T[宽度、高度];
    }
    }
    如果(x<宽度和y<高度)
    {
    __阵列2d[x,y]=val;
    }
    其他的
    {
    抛出新异常(x+”、“+Width+”、“+y+”、“+Height”);
    }
    }
    公共T这个[int x,int y]
    {
    得到
    {
    返回Get(x,y);
    }
    设置
    {
    设置(x,y,值);
    }
    }
    公共无效集(T[,]arr)
    {
    如果(arr!=null)
    {
    int rows=arr.GetLength(0);
    int cols=arr.GetLength(1);
    __array2d=arr;
    宽度=行;
    高度=cols;
    }
    其他的
    {
    抛出新异常(“数组为空”);
    }
    }
    #区域IDisposable实现
    ~Matrix()
    {
    本.处置(假);
    }
    受保护的布尔处置{get;private set;}
    公共空间处置()
    {
    这个。处置(真实);
    总干事(本);
    }
    受保护的虚拟void Dispose(bool disposing)
    {
    如果(!this.Disposed)
    {
    如果(处置)
    {
    //在此处执行托管清理。
    //IDisposable disp=(IDisposable)2du数组;
    __array2d=null;
    }
    //在此处执行非托管清理。
    宽度=0;
    高度=0;
    这是真的;
    }
    }
    #端区
    }
    
    二维锯齿矩阵

    公共类JagMatrix:IDisposable其中T:struct,IComparable
    {
    私人T[][]阵列2d;
    公共整数宽度{get;set;}
    公共整数高度{get;set;}
    公共图书馆是空的
    {
    得到
    {
    if(_array2d==null)返回true;
    否则返回false;
    }
    }
    公共JagMatrix(){}
    公共JagMatrix(T[][]数据)
    {
    本.集(数据);
    }
    公共JagMatrix(int行,int列)
    {
    宽度=行;
    高度=cols;
    __array2d=新的T[宽度][];
    对于(int i=0;iData Size          : 966 x 345
    Naked 2d Array     : 10 milliseconds
    Naked Jagged Array : 6 milliseconds
    Jagged Wrapper     : 82 milliseconds
    Dense Wrapper      : 88 milliseconds
    2d Wrapper         : 62 milliseconds
    
    Bitmap bmpImage = DataConverter2d.ReadGray("image.jpg");
    
    int[][] intNakedJagged = DataConverter2d.ToInteger(bmpImage);
    int[,] intNaked2d = JagMatrix<int>.To2d(intNakedJagged);
    
    JagMatrix<int> intJaggedWrapper = new JagMatrix<int>(intNakedJagged);
    DenMatrix<int> intDenWrapper = new DenMatrix<int>(intNaked2d);
    Matrix<int> int2dWrapper = new Matrix<int>(intNaked2d);
    
    Stopwatch sw1 = new Stopwatch();
    sw1.Start();
    double[,] dImage = DataConverter2d.ToDouble(intNaked2d);
    sw1.Stop();
    Console.WriteLine("Naked 2d Array : " + sw1.ElapsedMilliseconds.ToString() + " milliseconds", "Elapsed time");
    
    
    Stopwatch sw2 = new Stopwatch();
    sw2.Start();
    double[][] dImageJagged = DataConverter2d.ToDouble(intNakedJagged);
    sw2.Stop();
    Console.WriteLine("Naked Jagged Array : " + sw2.ElapsedMilliseconds.ToString() + " milliseconds", "Elapsed time");
    
    
    Stopwatch sw3 = new Stopwatch();
    sw3.Start();
    JagMatrix<double> dJagArray2d = DataConverter2d.ToDouble(intJaggedWrapper);
    sw3.Stop();
    Console.WriteLine("Jagged Wrapper : " + sw3.ElapsedMilliseconds.ToString() + " milliseconds", "Elapsed time");
    
    Stopwatch sw4 = new Stopwatch();
    sw4.Start();
    DenMatrix<double> dDenArray2d = DataConverter2d.ToDouble(intDenWrapper);
    sw4.Stop();
    Console.WriteLine("Dense Wrapper : " + sw4.ElapsedMilliseconds.ToString() + " milliseconds", "Elapsed time");
    
    Stopwatch sw5 = new Stopwatch();
    sw5.Start();
    Matrix<double> dArray2d = DataConverter2d.ToDouble(int2dWrapper);
    sw5.Stop();
    Console.WriteLine("2d Wrapper : " + sw5.ElapsedMilliseconds.ToString() + " milliseconds", "Elapsed time");
    
    Console.ReadKey();
    
    public class Matrix<T> : IDisposable where T : struct , IComparable<T>
    {
        private T[,] __array2d;
        public int Width { get; set; }
        public int Height { get; set; }
        public bool IsEmpty
        {
            get
            {
                if (__array2d == null) return true;
                else return false;
            }
        }
    
        public Matrix() { }
        public Matrix(T[,] data)
        {
            this.Set(data);
        }
    
        public Matrix(int rows, int cols)
        {
            Width = rows;
            Height = cols;
            __array2d = new T[Width, Height];
        }
        public T Get(int x, int y)
        {
            if (__array2d == null)
            {
                throw new Exception("array is empty");
            }
            if (x < Width && y < Height)
            {
                if (__array2d != null)
                {
                    return __array2d[x, y];
                }
                else
                {
                    throw new Exception("array is null");
                }
            }
            else
            {
                string message = string.Empty;
    
                if (x >= Width) message = "x-value exceeds Width ";
                if (y >= Height) message += "y-value exceeds Height ";
                message += "in Array2d.Get(x,y).";
                throw new Exception(message);
            }
        }
    
        public void Set(int x, int y, T val)
        {
            if (__array2d == null)
            {
                __array2d = new T[Width, Height];
            }
            else
            {
                if (Width != __array2d.GetLength(0))
                {
                    __array2d = null;
                    __array2d = new T[Width, Height];
                }
            }
    
            if (x < Width && y < Height)
            {
                __array2d[x, y] = val;
            }
            else
            {
    
                throw new Exception(x + ", " + Width + "," + y + "," + Height);
            }
        }
    
        public T this[int x, int y]
        {
            get
            {
                return Get(x, y);
            }
            set
            {
                Set(x, y, value);
            }
        }
    
        public void Set(T[,] arr)
        {
            if (arr != null)
            {
                int rows = arr.GetLength(0);
                int cols = arr.GetLength(1);
    
                __array2d = arr;
                Width = rows;
                Height = cols;
            }
            else
            {
                throw new Exception("array is null");
            }
        }
    
        #region IDisposable implementation
        ~Matrix()
        {
            this.Dispose(false);
        }
    
        protected bool Disposed { get; private set; }
    
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        protected virtual void Dispose(bool disposing)
        {
            if (!this.Disposed)
            {
                if (disposing)
                {
                    // Perform managed cleanup here.
                    //IDisposable disp = (IDisposable)_2dArray;
    
                    __array2d = null;
                }
    
                // Perform unmanaged cleanup here.
                Width = 0;
                Height = 0;
    
                this.Disposed = true;
            }
        }
        #endregion
    }
    
    public class JagMatrix<T> : IDisposable where T : struct , IComparable<T>
    {
        private T[][] __array2d;
        public int Width { get; set; }
        public int Height { get; set; }
        public bool IsEmpty
        {
            get
            {
                if (__array2d == null) return true;
                else return false;
            }
        }
    
        public JagMatrix() { }
        public JagMatrix(T[][] data)
        {
            this.Set(data);
        }
    
        public JagMatrix(int rows, int cols)
        {
            Width = rows;
            Height = cols;
    
            __array2d = new T[Width][];
            for (int i = 0; i < Width; i++)
            {
                __array2d[i] = new T[Height];
            }
        }
        public T Get(int x, int y)
        {
            if (__array2d == null)
            {
                throw new Exception("array is empty");
            }
            if (x < Width && y < Height)
            {
                if (__array2d != null)
                {
                    return __array2d[x][y];
                }
                else
                {
                    throw new Exception("array is null");
                }
            }
            else
            {
                string message = string.Empty;
    
                if (x >= Width) message = "x-value exceeds Width ";
                if (y >= Height) message += "y-value exceeds Height ";
                message += "in Array2d.Get(x,y).";
    
                throw new Exception(message);
            }
        }
    
        public void Set(int x, int y, T val)
        {
            if (__array2d == null)
            {
                __array2d = new T[Width][];
                for (int i = 0; i < Width; i++)
                {
                    __array2d[i] = new T[Height];
                }
            }
            else
            {
                if (Width != __array2d.GetLength(0))
                {
                    __array2d = null;
    
                    __array2d = new T[Width][];
                    for (int i = 0; i < Width; i++)
                    {
                        __array2d[i] = new T[Height];
                    }
                }
            }
    
            if (x < Width && y < Height)
            {
                __array2d[x][y] = val;
            }
            else
            {
    
                throw new Exception(x + ", " + Width + "," + y + "," + Height);
            }
        }
    
        public static T[,] To2d(T[][] source)
        {
            T[,] dest = new T[source.Length, source[0].Length];
    
            for (int i = 0; i < source.Length; i++)
            {
                for (int j = 0; j < source[0].Length; j++)
                {
                    dest[i,j] = source[i][j];
                }
            }
    
            return dest;
        }
    
        public T this[int x, int y]
        {
            get
            {
                return Get(x, y);
            }
            set
            {
                Set(x, y, value);
            }
        }
    
        public void Set(T[][] arr)
        {
            if (arr != null)
            {
                int rows = arr.Length;
                int cols = arr[0].Length;
    
                __array2d = arr;
    
                Width = rows;
                Height = cols;
            }
            else
            {
                throw new Exception("array is null");
            }
        }
    
        #region IDisposable implementation
        ~JagMatrix()
        {
            this.Dispose(false);
        }
    
        protected bool Disposed { get; private set; }
    
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        protected virtual void Dispose(bool disposing)
        {
            if (!this.Disposed)
            {
                if (disposing)
                {
                    // Perform managed cleanup here.
                    //IDisposable disp = (IDisposable)_2dArray;
    
                    __array2d = null;
                }
    
                // Perform unmanaged cleanup here.
                Width = 0;
                Height = 0;
    
                this.Disposed = true;
            }
        }
        #endregion
    }
    
    public class DenMatrix<T> : IDisposable where T : struct , IComparable<T>
    {
        private T[] __array1d;
        public int Width { get; set; }
        public int Height { get; set; }
        public int Length { get { return Width * Height; } }
        public bool IsEmpty
        {
            get
            {
                if (__array1d == null) return true;
                else return false;
            }
        }
    
        public DenMatrix() { }
        public DenMatrix(T[,] data)
        {
            this.Set(data);
        }
    
        public DenMatrix(int rows, int cols)
        {
            Width = rows;
            Height = cols;
    
            __array1d = new T[Length];
        }
    
        public T Get(int x, int y)
        {
            if (__array1d == null)
            {
                throw new Exception("array is empty");
            }
            if (x < Width && y < Height)
            {
                if (__array1d != null)
                {
                    return __array1d[x + y * Width];
                }
                else
                {
                    throw new Exception("array is null");
                }
            }
            else
            {
                string message = string.Empty;
    
                if (x >= Width) message = "x-value exceeds Width ";
                if (y >= Height) message += "y-value exceeds Height ";
                message += "in Array2d.Get(x,y).";
                throw new Exception(message);
            }
        }
    
        public void Set(int x, int y, T val)
        {
            int length = Length;
    
            if (__array1d == null)
            {
                __array1d = new T[length];
            }
            else
            {
                if (length != __array1d.Length)
                {
                    __array1d = null;
                    __array1d = new T[length];
                }
            }
    
            if (x < Width && y < Height)
            {
                __array1d[x + y * Width] = val;
            }
            else
            {
    
                throw new Exception(x + ", " + Width + "," + y + "," + Height);
            }
        }
    
        public T[] To1d(T[,] array2d)
        {
            T[] array1d = new T[Length];
    
            for (int x = 0; x < Height; x++)
            {
                for (int y = 0; y < Width; y++)
                {
                    T val = array2d[x, y];
    
                    int index = x * Width + y;
    
                    array1d[index] = val;
                }
            }
    
            return array1d;
        }
    
        public T this[int x, int y]
        {
            get
            {
                return Get(x, y);
            }
            set
            {
                Set(x, y, value);
            }
        }
    
        public void Set(T[,] arr)
        {
            if (arr != null)
            {
                int rows = arr.GetLength(0);
                int cols = arr.GetLength(1);
    
                Width = cols;
                Height = rows;
    
                __array1d = To1d(arr);
            }
            else
            {
                throw new Exception("array is null");
            }
        }
    
        #region IDisposable implementation
        ~DenMatrix()
        {
            this.Dispose(false);
        }
    
        protected bool Disposed { get; private set; }
    
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        protected virtual void Dispose(bool disposing)
        {
            if (!this.Disposed)
            {
                if (disposing)
                {
                    // Perform managed cleanup here.
                    //IDisposable disp = (IDisposable)_2dArray;
    
                    __array1d = null;
                }
    
                // Perform unmanaged cleanup here.
                Width = 0;
                Height = 0;
    
                this.Disposed = true;
            }
        }
        #endregion
    }
    
        public static double[][] ToDouble(int[][] image)
        {
            int Width = image.Length;
            int Height = image[0].Length;
    
            double[][] array2d = new double[Width][];
    
            for (int x = 0; x < Width; x++)
            {
                array2d[x] = new double[Height];
    
                for (int y = 0; y < Height; y++)
                {
                    double d = image[x][y] / 255.0;
    
                    array2d[x][y] = d;
                }
            }
    
            return array2d;
        }
    
        public static Matrix<double> ToDouble(Matrix<int> image)
        {
            int Width = image.Width;
            int Height = image.Height;
    
            Matrix<double> array2d = new Matrix<double>(Width, Height);
    
            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    double d = image[x, y] / 255.0;
    
                    array2d[x, y] = d;
                }
            }
    
            return array2d;
        }
    
    Data Size          : 4000 x 4000
    Naked 2d Array     : 188 milliseconds
    Naked Jagged Array : 202 milliseconds
    Jagged Wrapper     : 311 milliseconds
    Dense Wrapper      : 501 milliseconds
    2d Wrapper         : 343 milliseconds
    
    public T this[int x, int y]
    {
        get
        {
            try {
                return _array[x, y]; 
            } catch (IndexOutOfRangeException e) {
                throw new Exception(String.Format(
                    "index ({0}, {1}) exceeds size of Matrix ({2}, {3})",
                    x, y, Width, Height
                ));
            }
        }
        set
        {
            try {
                _array[x, y] = value; 
            } catch (IndexOutOfRangeException e) {
                throw new Exception(String.Format(
                    "index ({0}, {1}) exceeds size of Matrix ({2}, {3})",
                    x, y, Width, Height
                ));
            }
        }
    }
    
    Data Size          : 4000 x 4000
    Naked 2d Array     : 186 milliseconds
    matrix (2d Wrapper): 308 milliseconds
    FastMatrix         : 246 milliseconds
    
    public FastMatrix<R> Map<R>(Func<T, R> func) where R : struct, IComparable<R>
    {
        FastMatrix<R> array2d = new FastMatrix<R>(Width, Height);
    
        for (int x = 0; x < Width; x++)
        {
            for (int y = 0; y < Height; y++)
            {
                array2d._array[x, y] = func(_array[x, y]);
            }
        }
        return array2d;
    }
    
    FastMatrix<double> dFastMatrix2 = intFastMatrix.Map(v => (double)v / 255.0);
    
    Data Size          : 4000 x 4000
    Naked 2d Array     : 186 milliseconds
    matrix (2d Wrapper): 308 milliseconds
    FastMatrix.Map     : 184 milliseconds
    
    Data Size          : 4000 x 4000
    Naked 2d Array     : 186 milliseconds
    Naked Jagged Array : 200 milliseconds
    Jagged Wrapper     : 308 milliseconds
    Dense Wrapper      : 486 milliseconds
    2d Wrapper         : 308 milliseconds
    Fast versions:
    FastMatrix         : 246 milliseconds
    FastMatrix.Map     : 184 milliseconds
    
    Data Size          : 4000 x 4000
    Naked 2d Array     : 70 milliseconds
    Naked Jagged Array : 67 milliseconds
    Jagged Wrapper     : 205 milliseconds
    Dense Wrapper      : 391 milliseconds
    2d Wrapper         : 227 milliseconds
    Faster versions:
    FastMatrix         : 143 milliseconds
    FastMatrix.Map     : 130 milliseconds
    
    public ref T this[int x, int y] => ref __array2d[x, y];
    
    public ref T this[int x, int y] => ref __array2d[x][y];
    
    public ref T this[int x, int y] => ref __array1d[x + y * Width];
    
    Data Size          : 4000 x 4000
    Naked 2d Array     : 71 milliseconds
    Naked Jagged Array : 68 milliseconds
    Jagged Wrapper     : 77 milliseconds
    Dense Wrapper      : 355 milliseconds
    2d Wrapper         : 79 milliseconds
    Faster versions:
    FastMatrix         : 144 milliseconds
    FastMatrix.Map     : 132 milliseconds