数学建模社区-数学中国
标题:
为什么 C++ 只比 VBA 快 4倍?
[打印本页]
作者:
蕾欧娜
时间:
2015-4-20 10:09
标题:
为什么 C++ 只比 VBA 快 4倍?
用C++和VBA分别写了一段用随机数字测试
的值的算法,用500万个随机数,发现VBA需要570毫秒,而C++则需要150毫秒。这也太让人失望了把,C++写起来那么麻烦,起码也要快个几个数量级吧?python就更别说了,居然要7秒钟。求各位大神帮我看看是不是我的代码没优化好?
: H% o0 V; G3 i3 u9 {& x7 R
(平台是Visual Studio,已经开了Release模式)
- Z' g' w, q) }% c& I! }1 R
& F& d$ ]4 u! K
计算方法:生成
,
两个在0 到
之间的随机数,数一数这些数字里面有多少个落在了半径为
的1/4圆的扇形里面,用这个数字代表扇形面积,用总随机数数量代表正方形面积。因为扇形的面积是
,而正方形的面积是
, 可得知
=扇形面积/正方形面积 * 4
: {4 m: ~5 `8 s# V7 [; ^( G
' V& c! S v2 G# W% F/ T: X- i
C++代码:
+ l' @9 ?3 y" p8 l
#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;}
' A2 V/ |) `& [- Q% Q8 J
9 h; F& ^: K) ?: h6 L4 r% V
& N8 m' D) r |. e7 r
VBA代码:
$ k' k/ ?5 B" I; Z8 U6 V
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
8 y; ^ ?- k z8 K( h% _, ~
: @* {5 y- x) } ]; l: J- d
+ N. n! V5 R+ ~' {! a/ b2 G- Q
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)
3 m& X5 w. M( G5 Q" t( U
) ^9 a, B+ U, u2 X- D' H6 `
. f& L9 d* i- [* |( s
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5