在线时间 5 小时 最后登录 2015-5-8 注册时间 2015-4-8 听众数 9 收听数 0 能力 0 分 体力 53 点 威望 0 点 阅读权限 20 积分 25 相册 0 日志 0 记录 0 帖子 17 主题 19 精华 0 分享 0 好友 3
升级 21.05%
TA的每日心情 郁闷 2015-4-14 11:21
签到天数: 1 天
[LV.1]初来乍到
自我介绍 德玛西亚
用C++和VBA分别写了一段用随机数字测试 的值的算法,用500万个随机数,发现VBA需要570毫秒,而C++则需要150毫秒。这也太让人失望了把,C++写起来那么麻烦,起码也要快个几个数量级吧?python就更别说了,居然要7秒钟。求各位大神帮我看看是不是我的代码没优化好? $ z5 C) E. g: R, d, K2 s
(平台是Visual Studio,已经开了Release模式) 0 ]* z+ Y5 A: V5 O. ~) Y+ Q0 n) k! ~4 F& B
1 M8 Z2 g q# G( s 计算方法:生成 , 两个在0 到 之间的随机数,数一数这些数字里面有多少个落在了半径为 的1/4圆的扇形里面,用这个数字代表扇形面积,用总随机数数量代表正方形面积。因为扇形的面积是 ,而正方形的面积是 , 可得知 =扇形面积/正方形面积 * 4 + t2 H7 A$ s/ T% I5 p) M0 i+ M- \) j
1 \- C# |- H0 k C++代码: + M, @3 z' W* R+ B4 l- J: l2 n1 q( R
#include "stdafx.h" #include <iostream> #include <time.h> using namespace std;void main(){ double st = clock(); double rand_max = 32767 ; srand((int )time(0 )); unsigned int simulate_total = 2500000 ; unsigned int inside_count = 0 ; unsigned int radius = rand_max * rand_max; unsigned int randA; unsigned int randB; unsigned int randA_opp; unsigned int randB_opp; for (unsigned int i = 1 ; i < simulate_total; i++){ randA = rand(); randB = rand(); if ((randA * randA + randB * randB) < radius){ inside_count++; } randA_opp = rand_max - randA; randB_opp = rand_max - randB; if ((randA_opp * randA_opp + randB_opp * randB_opp) < radius){ inside_count++; } } cout << inside_count / double (simulate_total) * 2 << endl; cout << clock() - st << endl;}
1 M; X$ I+ ?- r, t! u
( g) N0 Q) g# }3 ~6 r6 y9 S : d& W, h- P4 @' G, M I Q
VBA代码: & O& f1 |. K' m0 \$ ]4 i
Sub simulate_pi ()Dim area_count As Double : area_count = 0 Dim simulate_count As Double : simulate_count = 2500000 Dim i As Double Dim randA As Double , randB As Double Dim randA_opp As Double , randB_opp As Double For i = 1 To simulate_count randA = Math.Rnd() randB = Math.Rnd() randA_opp = 1 - randA randB_opp = 1 - randB If randA * randA + randB * randB < 1 Then area_count = area_count + 1 End If If randA_opp * randA_opp + randB_opp * randB_opp < 1 Then area_count = area_count + 1 End IfNext iDebug.Print "Estimate: " , area_count / simulate_count * 2 End Sub'VBA内测时间的方法: '新建一个module,把以下代码复制进去,然后运行test. Option ExplicitPrivate Declare Function getFrequency Lib "kernel32" _Alias "QueryPerformanceFrequency" (cyFrequency As Currency) As Long Private Declare Function getTickCount Lib "kernel32" _Alias "QueryPerformanceCounter" (cyTickCount As Currency) As Long ' Function MicroTimer () As Double ' ' Returns seconds. ' Dim cyTicks1 As Currency Static cyFrequency As Currency ' MicroTimer = 0 ' Get frequency. If cyFrequency = 0 Then getFrequency cyFrequency' Get ticks. getTickCount cyTicks1' Seconds If cyFrequency Then MicroTimer = cyTicks1 / cyFrequencyEnd FunctionSub test () Dim st: st = MicroTimer Call simulate_pi Debug.Print (MicroTimer - st) * 1000 End Sub 1 Y+ K3 i5 h T) b( @9 V; o: j# e3 f
# U5 i- g: _, @. L2 v4 ^
$ h! X: Y% P- j6 s$ ~ Python代码: #!/usr/bin/python # Filename : pi_simulate.py import random import time time_start = time.perf_counter()inside_count = 0 simulate_total = 2500000 randA = 0 randB = 0 for i in range (1 , simulate_total): randA = random.uniform(0 ,1 ) randB = random.uniform(0 ,1 ) if ((randA * randA + randB * randB) < 1 ): inside_count = inside_count + 1 randA_opp = 1 - randA randB_opp = 1 - randB if ((randA_opp * randA_opp + randB_opp * randB_opp) < 1 ): inside_count = inside_count + 1 print (inside_count/simulate_total*2 )print ("Time spent" , time.perf_counter() - time_start)% ~6 O. s, j* D- t( V/ `
3 M3 H/ i+ {. r! I% Y # b$ l+ w6 x- F4 h0 o( K
zan