今天閒來無事,突然想測試一下C#,C++,Java這三種我比較常用的語言在浮點數運算方面的效率,大家可以先不急往下看,猜想一下結果如何。 首先是算法,采用計算一個100*100的Mandelbrot set,連續調用1000次來進行計時,算法來自於:http://www.nicholson.com/rhn/jsbench2.html,一個Javascript引擎的Benchmark(這裡再表揚下V8,不愧是最快的JS Engine,跑這個Benchmark,1.023秒,IE10還是有長進,1.163秒,差距不大,但是IE9,9秒......)。 OK,回歸到正題,下面是測試所用的代碼: 先是王者C語言:
#include <stdio.h> #include <stdlib.h> #include <time.h> int qset(float xx,float yy,float u,float v){ int n; float t,xsqr,ysqr; int lim = 100; float x = xx; float y = yy; xsqr = x*x; ysqr = y*y; for(n = 0;(n < lim) && (xsqr + ysqr < 4.0);n++){ t = xsqr - ysqr + u; y = 2.0 * x * y +v; x = t; xsqr = t * t; ysqr = y * y; } return n; } int mb100(){ int dots = 0; int res = 100; float a1 = -2.50; float b1 = -1.75; float s = 3.05; float x = 0; float y = 0; float g = s / res; int i,j,k; float a,b; for(j = 0,b = b1;j <res; b += g,j++){ for(i = 0,a = a1;i < res;a += g,i++){ k = qset(x,y,a,b); if(k > 90) { dots++; } } } return dots; } int main(int argc, char **argv) { clock_t start,finish; start=clock(); for(int i=0;i<1000;i++){ mb100(); } finish=clock(); long duration=finish-start; printf("%ld",duration);//1810 ms getchar(); return 0; }
再來是最受歡迎的JAVA:
public class Main { public static void main(String args[]) throws Exception{ long start=System.currentTimeMillis(); for(int i=0;i<1000;i++){ mb100(); } long finish=System.currentTimeMillis(); System.out.println(finish-start); //865ms } static int qset(float xx, float yy, float u, float v){ int n; float t, xsqr, ysqr; int lim = 100; float x = xx; float y = yy; xsqr = x * x; ysqr = y * y; for (n = 0; (n < lim) && (xsqr + ysqr < 4.0); n++) { t = xsqr - ysqr + u; y = 2.0f * x * y + v; x = t; xsqr = t * t; ysqr = y * y; } return n; } static int mb100(){ int dots = 0; int res = 100; float a1 = -2.50f; float b1 = -1.75f; float s = 3.05f; float x = 0; float y = 0; float g = s / res; int i, j, k; float a, b; for (j = 0, b = b1; j < res; b += g, j++) { for (i = 0, a = a1; i < res; a += g, i++) { k = qset(x, y, a, b); if (k > 90) { dots++; } } } return dots; } }
最後是開發效率最高的C#
#region 引用 using System; using System.Diagnostics; #endregion namespace MBTest { internal class Program { private static void Main(string[] args) { Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 1000; i++) { MB100(); } watch.Stop(); Console.WriteLine(watch.ElapsedMilliseconds);//1810 ms Console.ReadKey(); } private static int QSet(float xx, float yy, float u, float v) { int n; float t, xsqr, ysqr; int lim = 100; float x = xx; float y = yy; xsqr = x*x; ysqr = y*y; for (n = 0; (n < lim) && (xsqr + ysqr < 4.0); n++) { t = xsqr - ysqr + u; y = 2.0f*x*y + v; x = t; xsqr = t*t; ysqr = y*y; } return n; } private static int MB100() { int dots = 0; int res = 100; float a1 = -2.50f; float b1 = -1.75f; float s = 3.05f; float x = 0; float y = 0; float g = s/res; int i, j, k; float a, b; for (j = 0, b = b1; j < res; b += g, j++) { for (i = 0, a = a1; i < res; a += g, i++) { k = QSet(x, y, a, b); if (k > 90) { dots++; } } } return dots; } } }
輸出的結果已經注釋在代碼中了,我沒想到的是JAVA居然是最快的,而且還不是快了一星半點兒,只需要C/C#的50%左右,難道是JRE對運算專門做了優化?之前還用過計算SHA-512來進行比較,依然是JAVA最快,不知道是JRE優化還是編譯器優化了,有高手能解釋下麼。不過就C和C#來說,運算方面,只要C沒有做過特別優化,效率相差並不大(幾乎相同),但是C語言這種只有高手沒有菜鳥的語言,要想優化的更好,確實比較困難。