数学建模社区-数学中国
标题:
为什么 C++ 只比 VBA 快 4倍?
[打印本页]
作者:
蕾欧娜
时间:
2015-4-20 10:09
标题:
为什么 C++ 只比 VBA 快 4倍?
用C++和VBA分别写了一段用随机数字测试
的值的算法,用500万个随机数,发现VBA需要570毫秒,而C++则需要150毫秒。这也太让人失望了把,C++写起来那么麻烦,起码也要快个几个数量级吧?python就更别说了,居然要7秒钟。求各位大神帮我看看是不是我的代码没优化好?
! v4 o. _5 F8 F# q! Q3 T
(平台是Visual Studio,已经开了Release模式)
( j+ j8 n7 F. N! [: `4 O
! w1 y4 ]# {1 v6 ~! m/ Z
计算方法:生成
,
两个在0 到
之间的随机数,数一数这些数字里面有多少个落在了半径为
的1/4圆的扇形里面,用这个数字代表扇形面积,用总随机数数量代表正方形面积。因为扇形的面积是
,而正方形的面积是
, 可得知
=扇形面积/正方形面积 * 4
! n9 Q' i) \- H# x+ I; G6 _
" h& }( w9 Y g' V8 r* l, m
C++代码:
- ^6 |; B% f" i0 s% p
#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;}
: {$ a9 v. @% t1 ]
* T; Z0 f2 Y0 e; b6 S9 b
) v7 y8 o8 S2 D
VBA代码:
5 ]. C2 H( d+ E
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
" W! j+ \7 }" b1 |- y
* {& r; P% F3 J% j; W# x. a2 N
+ T/ e" R4 M5 Y" k6 U- y( n
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)
" V0 X$ D1 g3 ?- W& |% `+ b
/ i& } A9 H3 m) j) k9 B3 ^
/ k! K4 ~; O) E" V
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5