我有这个功能:
int round(double val) {
if (val >= 0) {
return (int)Math.Floor(val + 0.5);
}
return (int)Math.Ceiling(val - 0.5);
}
我在程序中多次调用它,我的意思是很多次,所以运行时间的每毫秒都是重要的。有什么方法可以使其比现在更快?谢谢
编辑:
该函数是用于计算图像中线的切线方向的算法的一部分。摘自学术文章。由于它以弧度值处理角度,因此使用小的精确数字。
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函数是最快的舍入方法吗?
您可以加快速度。这快了很多倍:
if (val >= 0)
{
return (int)(val + 0.5d);
}
return = (int)(val - 0.5d);
您避免使用所有这些Math库内容。问题是,这真的有关系吗?对于1500000转换,您第一个函数的时间为18ms。您的EDIT2函数为36ms。该功能为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");
}
一些注意事项
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句