zl程序教程

您现在的位置是:首页 >  后端

当前栏目

c++性能之对象与指针性能比较、以及java与c++性能对比实测

JAVAC++性能对象 以及 比较 对比 指针
2023-09-27 14:28:34 时间

为了更加直观的比较,好吧,我们选择以对象的初始化并add到list为例子。

首先,定义object如下:

#include <string>
#pragma once
using namespace std;
class FirstCPPCls
{

private:
    string serviceId;
    string systemId;
    string subSystemId;
    string appVersion;
    string companyId;
    string clusterName;
    
public:
    FirstCPPCls(void);
    ~FirstCPPCls(void);
    inline string getServiceId() { return serviceId;}
    inline string getSystemId() { return systemId;}
    inline string getSubSystemId() { return subSystemId;}
    inline string getAppVersion() { return appVersion;}
    inline string getCompanyId() { return companyId;}
    inline string getClusterName() { return clusterName;}

    inline void setServiceId(string v) { serviceId = v;}
    inline void setSystemId(string v) { systemId = v;}
    inline void setSubSystemId(string v) { subSystemId = v;}
    inline void setAppVersion(string v) { appVersion = v;}
    inline void setCompanyId(string v) { companyId = v;}
    inline void setClusterName(string v) { clusterName = v;}
}

测试代码:

    // 对象创建时间比较
    DWORD begin = GetTickCount();
    int f;
    vector<FirstCPPCls*> vO;
    for(i=0;i<100000;i++) {
        FirstCPPCls clz;
        clz.setAppVersion("12.32.33");
        clz.setClusterName("osm-service");
        clz.setCompanyId("239383");
        clz.setServiceId("sysL.1.223");
        clz.setSubSystemId("23");
        clz.setSystemId("32");
        vO.push_back(&clz);
    }
    cout << vO.size() << endl;
    DWORD end = GetTickCount();

    // 打印时间差
    cout << (end - begin) << endl;  // 平均4800豪秒左右
    system("pause");

java:

    public static void main(String[] args) {
        List<RouteItem> routeItems = new ArrayList<RouteItem>();
        System.out.println(System.currentTimeMillis());
        for(int i=0;i<100000;i++) {
            RouteItem clz = new RouteItem();
            clz.setAppVersion("12.32.33");
            clz.setClusterName("osm-service");
            clz.setCompanyId("239383");
            clz.setServiceId("sysL.1.223");
            clz.setSubSystemId("23");
            clz.setSystemId("32");
            routeItems.add(clz);
        }
        System.out.println(routeItems.size());
        System.out.println(System.currentTimeMillis());
// 平均15ms左右 }

好吧,cpp换成char*指针:

#include <string>
#pragma once
using namespace std;
class FirstCPPCls
{
private:
    char* serviceId;
    char* systemId;
    char* subSystemId;
    char* appVersion;
    char* companyId;
    char* clusterName;
    
public:
    FirstCPPCls(void);
    ~FirstCPPCls(void);
    inline char* getServiceId() { return serviceId;}
    inline char* getSystemId() { return systemId;}
    inline char* getSubSystemId() { return subSystemId;}
    inline char* getAppVersion() { return appVersion;}
    inline char* getCompanyId() { return companyId;}
    inline char* getClusterName() { return clusterName;}

    inline void setServiceId(char* v) { serviceId = v;}
    inline void setSystemId(char* v) { systemId = v;}
    inline void setSubSystemId(char* v) { subSystemId = v;}
    inline void setAppVersion(char* v) { appVersion = v;}
    inline void setCompanyId(char* v) { companyId = v;}
    inline void setClusterName(char* v) { clusterName = v;}
    
};

再测试,平均大约为46ms。还是比java慢啊。

再看大量代码中会用到的char[],如下:

#include <string>
#pragma once
using namespace std;
class FirstCPPCls
{
private:
    char serviceId[12];
    char systemId[4];
    char subSystemId[4];
    char appVersion[12];
    char companyId[6];
    char clusterName[12];
    
public:
    FirstCPPCls(void);
    ~FirstCPPCls(void);
    inline char* getServiceId() { return serviceId;}
    inline char* getSystemId() { return systemId;}
    inline char* getSubSystemId() { return subSystemId;}
    inline char* getAppVersion() { return appVersion;}
    inline char* getCompanyId() { return companyId;}
    inline char* getClusterName() { return clusterName;}

    inline void setServiceId(char* v) { 
        memset(serviceId,0,12);
        memcpy(serviceId,v,strlen(v));
    }
    inline void setSystemId(char* v) { 
        memset(systemId,0,4);
        memcpy(systemId,v,strlen(v));
    }
    inline void setSubSystemId(char* v) { 
        memset(subSystemId,0,4);
        memcpy(subSystemId,v,strlen(v));
    }
    inline void setAppVersion(char* v) { 
        memset(appVersion,0,12);
        memcpy(appVersion,v,strlen(v));
    }
    inline void setCompanyId(char* v) { 
        memset(companyId,0,6);
        memcpy(companyId,v,strlen(v));
    }
    inline void setClusterName(char* v) { 
        memset(clusterName,0,12);
        memcpy(clusterName,v,strlen(v));
    }
};

再测试,平均大约为62ms。还是比java慢啊,大部分情况下,处于可读性的考虑,应该使用第三种。

后面测试了vector、map之后,发现主要是cpp默认是value拷贝(简单地说可以认为java中的clone实现吧,当然细节相差还是很大的,尚且这么认为吧)的原因。使用指针后,内容复制消除了很多。

回到java,应该来说发展到jdk 6之后,虽然开发都用object,但是JVM内部将非primitive类型的所有对象都自动转换为指针操作了,而cpp因为要兼容早期的原因,不得不保留传统的机制。

注:上述测试是在msvc下测试的,换成gcc之后,string的速度可能会比char *要快,参考http://tieba.baidu.com/p/1038620654,大家可以进行测试。