作者GreatShot (我要拿Ph.D.!!!)
看板C_Sharp
标题Re: [问题] 练习题
时间Thu May 3 10:52:04 2007
: 另外,如果要算的次方数很大的话
: (应该到五次或是六次就应该呼叫了..)
: 建议呼叫 Math.Pow 会快上很多....
: 里面用的算法比你自己写的连乘法好很多..
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这点跟我认知很不一样
我没看过Math.Pow()的source所以不敢说它演算法好不好
我只能作实验来观察
source如下
public partial class Form1 : Form
{
[DllImport("kernel32.dll")]
extern static short QueryPerformanceCounter(ref long x);
[DllImport("kernel32.dll")]
extern static short QueryPerformanceFrequency(ref long x);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
long ctr1 = 0, ctr2 = 0, freq = 0;
double sum = 0;
double a = 0;
Random myrand = new Random();
if (QueryPerformanceCounter(ref ctr1)!=0) // Begin timing.
{
for (int i=0; i<1000000000; i++) // Code being timed.
{
a = myrand.NextDouble() * 10; //Generate Random number
//3 options
sum = 6 * (a * a * a) + (5 * (a * a)) + (3 * a) - 1;
//sum = 6*Math.Pow(a,3) + 5*Math.Pow(a,2)+(3*a) - 1;
//sum = a * (a * (a * (+6) + 5) + 3) - 1;
}
QueryPerformanceCounter(ref ctr2); // Finish timing.
this.richTextBox1.AppendText("Start Value: " + ctr1 + "\n");
this.richTextBox1.AppendText("End Value: " + ctr2+"\n");
QueryPerformanceFrequency(ref freq);
this.richTextBox1.AppendText("QueryPerformanceCounter minimum
resolution: 1/" + freq + " seconds."+"\n");
this.richTextBox1.AppendText("100 Increment time: " +
(ctr2 - ctr1) * 1.0 / freq + " seconds."+"\n");
}
else
this.richTextBox1.AppendText("High-resolution counter not
supported."+"\n");
}
}
Result1: sum = 6 * (a * a * a) + (5 * (a * a)) + (3 * a) - 1;
Start Value: 757143142739
End Value: 757167788963
QueryPerformanceCounter minimum resolution: 1/14318180 seconds.
100 Increment time:
1.72132379953318 seconds.
Result2: sum = 6*Math.Pow(a,3) + 5*Math.Pow(a,2)+(3*a) - 1;
Start Value: 758355648048
End Value: 758755628202
QueryPerformanceCounter minimum resolution: 1/14318180 seconds.
100 Increment time:
27.9351254139842 seconds.
Result3: sum = a * (a * (a * (+6) + 5) + 3) - 1;
Start Value: 759758768779
End Value: 759783404913
QueryPerformanceCounter minimum resolution: 1/14318180 seconds.
100 Increment time:
1.720619101031 seconds.
再来换成幂次更高的
Result1: sum =
9 * (a * a * a * a * a * a) + 8 * (a * a * a * a * a) +
7 * (a * a * a * a) + 6 * (a * a * a) + (5 * (a * a)) + (3 * a) - 1;
Start Value: 766926901793
End Value: 766951596182
QueryPerformanceCounter minimum resolution: 1/14318180 seconds.
100 Increment time:
1.72468770472225 seconds.
Result2: sum =
9 * Math.Pow(a, 6) + 8 * Math.Pow(a, 5) + 7 * Math.Pow(a, 4) + 6 *
Math.Pow(a, 3) + 5 * Math.Pow(a, 2) + (3 * a) - 1;
Start Value: 769278944190
End Value: 770282636993
QueryPerformanceCounter minimum resolution: 1/14318180 seconds.
100 Increment time:
70.0991887935478 seconds.
Result3: sum =
a * (a * (a * ( a * (a * (a * (+9) +8) +7 ) +6) + 5) + 3) - 1;
Start Value: 774103750407
End Value: 774128401956
QueryPerformanceCounter minimum resolution: 1/14318180 seconds.
100 Increment time:
1.72169570434231 seconds.
这实验其实很粗糙
但是可以看的出有非常明显的差异
由此看来
第一种写法跟第三种写法几乎是没有差别的
也许是.net compiler会自己最佳化
但是第二种(使用Math.Pow())
很明显的在执行时间上有段落差
幂次越大差距就越大
所以我的认知是要求效率的时候用连乘法会比Math.Pow()来的好
不过
也许是我实验的方式有误
有错的话麻烦请各位贤达指正
谢谢 :)
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.133.110.47
1F:推 yoco315:你是对的.. 我弄错了 :) 05/03 11:08
2F:推 GreatShot:因为我吃过亏 所以印象深刻 :) 05/03 13:08
3F:推 cole945:可能Math.Pow的overhead主要来自於function call? 05/03 13:15
4F:→ cole945:我在我的电脑上测, Math.Pow(a,x) x在300以内,都是大约固 05/03 13:15
5F:→ cole945:定在0.22ms左右, 可是a*a*a..却很虽然连乘数增加@.@a 05/03 13:16
6F:→ cole945: (我最後一句话的 "虽然" 是要打 "随着" |||| ) 05/03 13:18
7F:推 GreatShot:我也不知道为何 我执行Math.Pow(a,100)远比连乘100次慢 05/03 13:41
8F:→ GreatShot:我用的OS是Vista 64, 不知换个OS跑会不会有不同的结果 05/03 13:42
9F:推 birdychang:QueryPerformanceCounter跟Environment.TickCount 05/03 19:38
10F:→ birdychang:有不同吗?? 05/03 19:39
11F:→ birdychang:我是都用Environment.TickCount算时间耶~ 05/03 19:39
12F:推 GreatShot:楼上~精确度不同~~ 05/04 06:58
13F:→ GreatShot:精确度 QPC > TickCount > Timer 05/04 06:59
14F:推 chhuang:我倒是都用 StopWatch 来测试时间... 05/04 11:12
15F:推 GreatShot:我记得stopwatch就是用QPC来写的 05/04 11:22
16F:→ GreatShot:so其实stopwatch应该是最好用的 XD 05/04 11:25
17F:推 Epimenides:刚试用了stopwatch 好用 05/05 18:14