您的位置:首页 > 其它

腾讯马拉松之小Q系列故事——屌丝的逆袭

2013-03-25 00:00 155 查看
今天闲得无聊,突发奇想,做了一个Java和C++的性能对比测试。

 

1 测试方法

  很简单的,就是分别让Java程序和C++程序做很多次的整数和浮点数运算,然后测量测试代码段的运行时间。C++代码中使用Windows函数QueryPerformanceCounter() 获取CPU的高精度计数值,测试开始前后分别获取一次计数值,使用Windows函数QueryPerformanceFrequency()获取运行频率,前后的计数差值除以频率就得到了运行时间。为了使时间测量基准一致,在Java程序中通过JNI去调用这两个Windows函数,测量Java程序的运行时间。

  下面分别给出代码。

 

2 C++测试代码

 

#include "stdafx.h"
#include "windows.h"
#include <iostream>
#include <cmath>
using namespace std;

const int INT_C = 200000;
const int DOU_C = 50000;
const int MAIN_C = 10000;

class Test {
public:
Test();
void testInt();
void testDouble();
void doTest();
private:
int m_i;
double m_d;
};

Test::Test()
{
m_i = 0;
m_d = 0.0;
}

void Test::testInt()
{
for (int i=1;i<= INT_C;i++) {
m_i = (~(i*7) + 0x963 - i) & (i / 3);
}
}

void Test::testDouble()
{
for (int i=1;i<= DOU_C;i++) {
m_d = ((i<<2) + 0.36954) * sin((double)i);
}
}

void Test::doTest()
{
testInt();
testDouble();
}

int _tmain(int argc, _TCHAR* argv[])
{
LARGE_INTEGER freq;
LARGE_INTEGER start;
LARGE_INTEGER end;
QueryPerformanceFrequency(&freq);

Test* test = NULL;
int j;

cout<<"start test..."<<endl;

QueryPerformanceCounter(&start);
for (j = 0;j < MAIN_C; j++) {
test = new Test();
test->doTest();
delete test;
}
QueryPerformanceCounter(&end);

double druation = ((double)(end.QuadPart - start.QuadPart)) / ((double)freq.QuadPart);
cout<<"Program run druation: "<<druation*1000<<" ms."<<endl;

return 0;
}

 

 3 Java测试代码

3.1 测试代码

 

public class PerformTest {
public static final int INT_C = 200000;
public static final int DOU_C = 50000;
public static final int MAIN_C = 10000;

private int m_i;
private double m_d;

public void testInt() {
for (int i=1;i<= INT_C;i++) {
m_i = (~(i*7) + 0x963 - i) & (i / 3);
}
}

public void testDouble() {
for (int i=1;i<= DOU_C;i++) {
m_d = ((i<<2) + 0.36954) * Math.sin((double)i);
}
}

public void doTest() {
testInt();
testDouble();
}

public static void main(String[] args) {
PerformanceTimer timer = new PerformanceTimer();
PerformTest test = null;
int j;
System.out.println("start test...");

timer.start();
for (j = 0;j < MAIN_C; j++) {
test = new PerformTest();
test.doTest();
test = null;
}
double duration = timer.end();

System.out.println("Program run druation: " + duration + " ms.");
}
}

 

 3.2 实现时间测量的代码

 

public class PerformanceTimer {
private double freq;
private double startTime;
private double endTime;

public PerformanceTimer() {
this.freq = queryPerformanceFrequency();
}

private native double queryPerformanceFrequency();

private native double QueryPerformanceCounter();

public void start() {
this.startTime = QueryPerformanceCounter();
}

public double end() {
this.endTime = QueryPerformanceCounter();
double duration = (endTime - startTime) / freq * 1000;
return duration;
}

static {
try {
System.loadLibrary("PerformanceTimer");
} catch (Exception e) {
e.printStackTrace();
}
}
}

 

 3.3 实现时间测量的本地C++代码

    省略javah生成的头文件,给出实现的源文件。

 

#include "stdafx.h"
#include "windows.h"
#include "PerformanceTimer.h"

JNIEXPORT jdouble JNICALL Java_PerformanceTimer_queryPerformanceFrequency
(JNIEnv *, jobject)
{
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);

return (double)(freq.QuadPart);
}

JNIEXPORT jdouble JNICALL Java_PerformanceTimer_QueryPerformanceCounter
(JNIEnv *, jobject)
{
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);

return (double)(counter.QuadPart);
}

 

 

4 测试结果

  我的软硬件环境:

  硬件配置:AMD AthlonII X3 435 2.89GHz; 2GB DDR3内存;WD 500G硬盘;

  软件环境:Windows7 旗舰版;Visual C++ 2008;SUN jdk1.6.0_21.

 

  C++测试结果:

 

第一次第二次第三次平均时间
时间(单位:ms)21023.621003.521014.721013.9

 

  Java测试结果:

第一次第二次第三次平均时间
时间(单位:ms)94369.494317.394347.294344.6
 

C++程序的性能竟是Java的3倍?这真的是他们之间真实的性能差距吗?我所用的测试方法是否科学呢?那么影响我们的Java程序的性能瓶颈在什么地方?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: