最近在開發一些很講求速度的程式,對於"程式夠不夠快"這件事有了全新的體認!
以往寫Web時,User多半很能忍受看網頁本來就需要等待這件事實,所以只要不太離諎,3,5秒的Delay多半還可被接受。而最近在處理的案子是那種速度絕對至上的典型,慢了1ms程式就變成廢柴,因此每個環節都要求快,變成不能用傳統正規的做法解決,到處都在走偏鋒,才能達成目標。
CodeProject上有篇很棒的研究--Timer Surprises,看過之後才發現Timer.Interval設成15ms以下根本就是自欺欺人,而文中所附的程式是個很好的實證,可以測試你的電腦如何實現Timter.Interval 1ms, Thread.Sleep 1ms,結果會讓你很吃驚。
在我的兩台號稱旗艦的主機上執行的結果,Thread.Sleep可以達到極接近的精確度,滿心歡喜地想應用在試測環境上,沒想到... 天哪,結果竟不相同。於是我簡化了程式碼,寫了一個Console Application-TestThreadSleep,蒐集手邊幾台機器的執行結果,發現一個很有趣的事實! 如同Timer Surprises文中所說的,作者沒找出決定Thread.Sleep實際停止時間的因素,我也暫無定論(但有些推測)。
以下是我的測試結果:
XPC SD27P2 Core 2 Duo E6400 2.16G Win 2003
Thread.Sleep(25) Test:
25.374 ms, 25.261 ms, 25.337 ms, 25.362 ms, 25.241 ms, Avg = 25.315 ms
Thread.Sleep(15) Test:
15.484 ms, 15.581 ms, 15.580 ms, 15.563 ms, 15.573 ms, Avg = 15.556 ms
Thread.Sleep(10) Test:
10.618 ms, 10.707 ms, 10.689 ms, 10.708 ms, 10.688 ms, Avg = 10.682 ms
Thread.Sleep(5) Test:
5.216 ms, 5.686 ms, 5.812 ms, 5.822 ms, 5.817 ms, Avg = 5.671 ms
Thread.Sleep(1) Test:
1.362 ms, 1.906 ms, 1.915 ms, 1.917 ms, 1.916 ms, Avg = 1.803 ms
IBM ThinkPad X21 PIII-700M Hz XP
Thread.Sleep(25) Test:
24.025 ms, 29.655 ms, 29.990 ms, 30.028 ms, 29.986 ms, Avg = 28.737 ms
Thread.Sleep(15) Test:
19.893 ms, 20.020 ms, 19.994 ms, 19.943 ms, 19.971 ms, Avg = 19.964 ms
Thread.Sleep(10) Test:
9.930 ms, 9.999 ms, 9.983 ms, 10.003 ms, 9.977 ms, Avg = 9.978 ms
Thread.Sleep(5) Test:
9.929 ms, 10.009 ms, 10.112 ms, 9.998 ms, 9.973 ms, Avg = 10.004 ms
Thread.Sleep(1) Test:
9.985 ms, 9.797 ms, 9.990 ms, 10.004 ms, 9.981 ms, Avg = 9.951 ms
XPC SB91P P4 3.2G Vista
Thread.Sleep(25) Test:
24.541 ms, 25.147 ms, 25.260 ms, 25.282 ms, 25.236 ms, Avg = 25.093 ms
Thread.Sleep(15) Test:
15.472 ms, 15.535 ms, 15.531 ms, 15.523 ms, 15.523 ms, Avg = 15.517 ms
Thread.Sleep(10) Test:
10.606 ms, 10.647 ms, 10.607 ms, 10.649 ms, 10.616 ms, Avg = 10.625 ms
Thread.Sleep(5) Test:
5.700 ms, 5.743 ms, 5.819 ms, 5.693 ms, 5.780 ms, Avg = 5.747 ms
Thread.Sleep(1) Test:
1.842 ms, 1.910 ms, 1.884 ms, 1.860 ms, 1.894 ms, Avg = 1.878 ms
HP Proliant DL360 G3 P4 3.4G Win2003
Thread.Sleep(25) Test:
29.770 ms, 30.159 ms, 30.941 ms, 31.194 ms, 31.180 ms, Avg = 30.649 ms
Thread.Sleep(15) Test:
15.682 ms, 15.323 ms, 15.551 ms, 15.604 ms, 15.561 ms, Avg = 15.544 ms
Thread.Sleep(10) Test:
15.458 ms, 15.576 ms, 15.819 ms, 15.373 ms, 15.456 ms, Avg = 15.536 ms
Thread.Sleep(5) Test:
15.454 ms, 15.599 ms, 15.605 ms, 15.468 ms, 15.809 ms, Avg = 15.587 ms
Thread.Sleep(1) Test:
15.269 ms, 15.562 ms, 15.513 ms, 15.559 ms, 15.555 ms, Avg = 15.491 ms
HP Proliant DL360 P-III 1.26G Win 2000
Thread.Sleep(25) Test:
23.968 ms, 31.266 ms, 30.447 ms, 31.165 ms, 31.041 ms, Avg = 29.577 ms
Thread.Sleep(15) Test:
15.682 ms, 15.291 ms, 15.557 ms, 15.521 ms, 15.550 ms, Avg = 15.520 ms
Thread.Sleep(10) Test:
15.486 ms, 15.463 ms, 15.682 ms, 15.418 ms, 15.517 ms, Avg = 15.513 ms
Thread.Sleep(5) Test:
15.472 ms, 15.552 ms, 15.535 ms, 15.569 ms, 15.709 ms, Avg = 15.568 ms
Thread.Sleep(1) Test:
15.290 ms, 15.539 ms, 15.559 ms, 15.551 ms, 15.554 ms, Avg = 15.499 ms
由這個結果來看,Thead.Sleep下去會不會準時起床似乎非關CPU快慢,倒是跟主機板比較有關(例如: 兩台XPC一致,兩台ProLiant Server一致),兩台HP主機,似乎還是卡在無法切出小於15ms的精確度,小黑X21則是努力的要精準,無奈CPU力不從心~~~
只是由這個結論來看,想利用Thread.Sleep更精準控制時間的構想會因機器不同而破功,看來是不可行的,殘念!