Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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 - Fatal编程技术网

C# 我可以加快我的特殊轮功能吗?

C# 我可以加快我的特殊轮功能吗?,c#,performance,C#,Performance,我有这个功能: int round(double val) { if (val >= 0) { return (int)Math.Floor(val + 0.5); } return (int)Math.Ceiling(val - 0.5); } 我在程序中多次调用它,我是说多次,所以它的每一毫秒运行时间都很重要。有没有办法比现在快一点?Thx 编辑: 该函数是计算图像中直线切线方向的算法的一部分。它摘自学术文章。当它处理弧度值中的角度时,它使用小

我有这个功能:

int round(double val) {
    if (val >= 0) {
        return (int)Math.Floor(val + 0.5);
    }
    return (int)Math.Ceiling(val - 0.5);
}
我在程序中多次调用它,我是说多次,所以它的每一毫秒运行时间都很重要。有没有办法比现在快一点?Thx

编辑:

该函数是计算图像中直线切线方向的算法的一部分。它摘自学术文章。当它处理弧度值中的角度时,它使用小而精确的数字

I/O示例:

0 -> 0
1 -> 1
1.1 -> 1
1.51 -> 2
-0.1 -> 0
-1 -> -1
-1.1 -> -1
-1.51 -> -2
编辑2:

根据评论,我将已检查的函数更改为以下函数:

int round(double val) {
    return (int)Math.Round(val, MidpointRounding.AwayFromZero);
}

更新的问题是:Math.Round函数是最快的取整方法吗?

为什么不使用内置的
Math.Round
方法

int round(double val) {
    if (val >= 0) {
        return Math.Round(val, MidpointRounding.AwayFromZero);
    }
    return Math.Round(val, MidpointRounding.ToEven);
}

您可以加快速度。这要快很多倍:

        if (val >= 0)
        {
            return (int)(val + 0.5d);
        }
        return = (int)(val - 0.5d);
你避免了那些数学库的东西。问题是,这真的重要吗?对于1500000次转换,第一个函数的时间为18ms。您的EDIT2函数是36毫秒。这个函数是4ms

根据这种测量,处理器可以在大约2,5ns的时间内比较两个双精度,添加两个双精度,并转换一个双精度。但如果缓存中没有,则从主内存读取可能需要100ns。测量有时会产生误导

这是完整的代码

#region stopky

        public class Stopky
        {
            [System.Runtime.InteropServices.DllImport("kernel32.dll")]
            private static extern bool QueryPerformanceFrequency(out long frequency);

            [System.Runtime.InteropServices.DllImport("kernel32.dll")]
            private static extern bool QueryPerformanceCounter(out long ticks);

            protected static double frequency = -1;

            public void setStart()
            {
                QueryPerformanceCounter(out tickStart);
            }

            public double getTimeFromStart
            {
                get
                {
                    QueryPerformanceCounter(out tickNow);
                    double time = (tickNow - tickStart) / frequency;
                    return time;
                }
            }

            private long tickStart;
            private long tickNow;

            public Stopky()
            {
                if (frequency < 0)
                {
                    long tmp;
                    QueryPerformanceFrequency(out tmp);

                    if (tmp == 0)
                    {
                        throw new NotSupportedException("Error while querying "
               + "the high-resolution performance counter.");
                    }

                    frequency = tmp;
                }

                setStart();
            }

            public void Show()
            {
                MessageBox.Show(this.getTimeFromStart.ToString());
            }


        }

        #endregion




        private void button2_Click(object sender, EventArgs e)
        {
            double[] examples = new double[] { 0, 1, 1.1, 1.51, -0.1, -1, -1.1, -1.51 };

            int totalCount = 1500000;

            double[] examplesExpanded = new double[totalCount];

            for (int i = 0, j = 0; i < examplesExpanded.Length; ++i)
            {
                examplesExpanded[i] = examples[j];

                if (++j >= examples.Length) { j = 0; }
            }

            int[] result1 = new int[totalCount];
            int[] result2 = new int[totalCount];
            int[] result3 = new int[totalCount];

            Stopky st = new Stopky();
            for (int i = 0; i < examplesExpanded.Length; ++i)
            {
                result1[i] = (int)Math.Round(examplesExpanded[i], MidpointRounding.AwayFromZero);
            }
            st.Show();
            st = new Stopky();
            for (int i = 0; i < examplesExpanded.Length; ++i)
            {
                double val = examplesExpanded[i];
                if (val >= 0)
                {
                    result2[i] = (int)Math.Floor(val + 0.5);
                }
                result2[i] = (int)Math.Ceiling(val - 0.5);
            }
            st.Show();
            st = new Stopky();
            for (int i = 0; i < examplesExpanded.Length; ++i)
            {
                double val = examplesExpanded[i];
                if (val >= 0)
                {
                    result3[i] = (int)(val + 0.5d);
                }
                else
                {
                    result3[i] = (int)(val - 0.5d);
                }
            }
            st.Show();

            for (int i = 0; i < totalCount; ++i)
            {
                if(result1[i] != result2[i] || result1[i] != result3[i])
                {
                    MessageBox.Show("ERROR");
                }
            }
            MessageBox.Show("OK");

        }
#区域stopky
公共级停车场
{
[System.Runtime.InteropServices.DllImport(“kernel32.dll”)]
专用静态外部布尔查询性能频率(输出长频率);
[System.Runtime.InteropServices.DllImport(“kernel32.dll”)]
专用静态外部布尔查询性能计数器(输出长刻度);
受保护静态倍频=-1;
公共void setStart()
{
QueryPerformanceCounter(out-tickStart);
}
公共双getTimeFromStart
{
得到
{
QueryPerformanceCounter(立即退出);
双倍时间=(滴答声-滴答声开始)/频率;
返回时间;
}
}
私人长期启动;
现在是私人长假;
公共停车场()
{
中频(频率<0)
{
长tmp;
查询性能频率(输出tmp);
如果(tmp==0)
{
抛出新的NotSupportedException(“查询时出错”
+“高分辨率性能计数器”);
}
频率=tmp;
}
setStart();
}
公开展览(
{
Show(this.getTimeFromStart.ToString());
}
}
#端区
私有无效按钮2\u单击(对象发送者,事件参数e)
{
double[]示例=新的double[]{0,1,1.1,1.51,-0.1,-1,-1.1,-1.51};
int totalCount=1500000;
double[]exampleSpanded=新的double[totalCount];
对于(int i=0,j=0;i=examples.Length){j=0;}
}
int[]result1=新的int[totalCount];
int[]result2=新的int[totalCount];
int[]result3=新的int[totalCount];
Stopky st=新Stopky();
对于(int i=0;i=0)
{
结果2[i]=(int)数学下限(val+0.5);
}
结果2[i]=(int)数学上限(val-0.5);
}
圣秀();
st=新Stopky();
对于(int i=0;i=0)
{
结果3[i]=(int)(val+0.5d);
}
其他的
{
结果3[i]=(int)(val-0.5d);
}
}
圣秀();
对于(int i=0;i
一些注释

  • i
  • 发布可以比调试快很多(这里的区别不大)

我不认为您的建议是正确的-例如,当我的val=-5时,您的将返回-6,而我的将返回-5。。。积极的价值观也有问题,也许我误解了你的意图。你能用一些输入和输出的例子来编辑你的问题吗?为什么你的方法写得像现在这样?看看你的编辑,我认为你不需要做任何检查,只要
Math.Round(val,middpointrounding.AwayFromZero)当我深入研究它时,似乎我做到了…:-)但仍然存在一个问题,那就是是否有更好的实施方法。我的意思是,Math.round函数是对数字进行舍入的最快方法吗?如果不进行一些性能测试,它可能是不实现较低级别舍入算法的最快方法。根据您的应用程序和运行它的硬件,我怀疑您是否能够实现性能的大幅提升。您刚才不是说过吗