读书人

C/C++amp;Java 字符串拼接效率对比(下部

发布时间: 2012-12-23 11:28:15 作者: rapoo

C/C++&Java 字符串拼接效率对比(上部)[内容超过长度被截断完成可以下载文档和源码]

C/C++&Java字符串拼接效率对比

??? C/C++拼接字符串的方式很多,尤其是所谓的”VC++”语言(不应该称其为语言,但是很多使用VC++的程序员却把它变成了VC++语言即微软血统的C++语言)中这种方式又变多一些。在Windows下的Visual C++中很多的程序员习惯使用微软MFC中CString 。虽然使用MFC编程时使用CString来处理字符串的确有着与MFC库配合的便利。但是在开发中如果并没有用到MFC的时候我建议还使用 Standard C++的字符串。好处很多首先它是标准的意味着你使用它(std::string, std::wstring)来处理字符串。并且你的程序没有使用与具体操作系统相关的API (或使用了跨平台的相关类库代替)。 那么意味着你的代码在有对应平台的并且符合C++标准的编译器下可以直接编译通过。也意味着你的程序具备较好的跨平台能力。另外在性能方面也较为出色。下面测试了一下在VC++2008中各种字符串拼接方式的性能对比。当然这里面有有预分配方式的,测试程序中最后会根据每一项的耗时进行排序,当然排序的结果需要看是否采用预分配方式。当然C++ std::string, std::wstring中有一些提高效率的机制(在非预分配方式下)。然后又在Java中测试了一下字符Java的StringBuffer及StringBuilder字符串拼接效率也很不错。最后测试的结果有助于指导我们使用最高效的方式处理字符处拼接。

?

以下测试代码:

注:在 const int TEST_TIMES = 9000000;时C的memcpy使用16-32 ms(毫秒) std::string 也在 1000 ms(毫秒)左右。由于其他的方式耗时过长因此将 TEST_TIMES = 90000次在Java中普通的String也是如此.

#include "stdafx.h"

#include <string>

#include <sstream>

#include <iostream>

#include <cassert>

#include <cstring>

#include <ctime>

#include <vector>

#include <algorithm>

#include <afxwin.h>

?

using namespace std;

?

?

const int????? TEST_TIMES????????????? = 90000;

const char?? APPEND_CONTENT[]?????? = "cppmule";

const int????? PREALLOCATE_SIZE = strlen(APPEND_CONTENT) * TEST_TIMES+ 1;

?

class Statistic {

public:

?????? string item;

?????? int used;

?????? friend inline ostream & operator<< (ostream & os, const Statistic &stat){

????????????? os?? <<"item: " << stat.item<< endl

??????????????????????????? <<"used: " << stat.used<< " ms." << endl << endl;

????????????? return os;

?????? }

??????

?????? inline bool operator>(const Statistic& stat){

????????????? return (used > stat.used);

?????? }

?

?????? inline bool operator<(const Statistic& stat){

????????????? return (used < stat.used);

?????? }

};

?

vector<Statistic> g_statistics;

?

#define BEGIN_TICK() \

?????? clock_t start =clock();

?

#define END_AND_PRINT_TICK(info)????? \

?????? clock_t used = clock() - start;???? ?????? \

?????? Statistic stat;?????????????????? ????????????? \

?????? stat.item.assign(info);?????????? ?????? \

?????? stat.used = used;???????????? ????????????? \

?????? g_statistics.push_back(stat);????? ?????? \

?????? cout << info<< " Used: " << used << "ms." << endl;

?

#define PRINT_SORT_TEST_TICKS()?????? ???????????????????? \

?????? sort(g_statistics.begin(), g_statistics.end());?????? ?????? \

?????? struct StatisticPrinter{ ???????????????????? ?????? \

????????????? StatisticPrinter() : order(0) {}????????? ?????? \

????????????? void operator() (const Statistic&stat) {? ?????? \

???????????????????? ++order;????? ???????????????????? ?????? \

???????????????????? cout << "sortorder: " << order <<endl?? \

?????????????????????????????????? ?<< stat;????? ?????? ?????? \

????????????? }???? ?????????????????????????????????? ?????? \

????????????? int order;???? ??????????????????????????? ?????? \

?????? } printer;???? ????????????????????????????????????????? \

cout << "---------Statisticsinformations(sorting ascendent)-------" << endl << endl;???? \

?????? for_each(g_statistics.begin(), g_statistics.end(), printer);\

?????? cout << "----------------------"<< endl;

?

?

void test_stdstring_append()

{

?????? string str;

?????? BEGIN_TICK();

?????? for (int i=0; i<TEST_TIMES; i++){

????????????? str.append(APPEND_CONTENT);

?????? }

?????? END_AND_PRINT_TICK("std::stringappend");

?????? cout << "stringlength: " << str.length() << endl;

}

?

void test_stdstring_append_operator()

{

?????? string str;

?????? BEGIN_TICK();

?????? for (int i=0; i<TEST_TIMES; i++){

????????????? str += APPEND_CONTENT;

?????? }

?????? END_AND_PRINT_TICK("std::string+= operator");

?????? cout << "stringlength: " << str.length() << endl;

}

?

void test_stdostringstream()

{

?????? ostringstream oss;

?????? BEGIN_TICK();

?????? for (int i=0; i<TEST_TIMES; i++){

????????????? oss << APPEND_CONTENT;

?????? }

?????? END_AND_PRINT_TICK("std::ostringstream<<");

?????? cout << "stringlength: " << oss.str().length()<< endl;

}

?

void test_stdostringstream_preallocate()

{

?????? ostringstream oss;

?????? BEGIN_TICK();

?????? for (int i=0; i<TEST_TIMES; i++){

????????????? oss << APPEND_CONTENT;

?????? }

?????? END_AND_PRINT_TICK("std::ostringstream<<");

?????? cout << "stringlength: " << oss.str().length()<< endl;

}

?

void test_stdstring_append_operator_preallocate()

{

?????? string str;

?????? str.reserve(PREALLOCATE_SIZE);

?????? cout << "capacity:" << str.capacity() << endl

????????????? << "size: " << str.size()<< endl;

?????? //assert(str.capacity() == 1024*1024*512);

?????? BEGIN_TICK();

?????? for (int i=0; i<TEST_TIMES; i++){

????????????? str += APPEND_CONTENT;

?????? }

?????? END_AND_PRINT_TICK("havaresize(PREALLOCATE_SIZE) std::string += operator");

?????? cout << "stringlength: " << str.length() << endl;

}

?

void test_c_strcat_append()

{

?????? char* pstr = (char*)malloc(PREALLOCATE_SIZE);

?????? memset(pstr, 0,sizeof(pstr));

?

?????? BEGIN_TICK();

?????? for (int i=0; i<TEST_TIMES; i++){

????????????? strcat(pstr, APPEND_CONTENT);

?????? }

?????? END_AND_PRINT_TICK("cstring function strcat:");

?????? cout << "stringlength: " << strlen(pstr) << endl;

?

?????? free(pstr);

?????? pstr = NULL;

}

?

void test_c_memcpy_append()

{

?????? //Allocate memory

?????? char* pstr = (char*)malloc(PREALLOCATE_SIZE);

?????? if (NULL == pstr) {

????????????? cerr << "Can'tallocate memory." << endl;

????????????? return;

?????? }

?????? memset(pstr, 0,PREALLOCATE_SIZE);

?

?????? BEGIN_TICK();

?????? int len = 0;

?????? for (int i=0; i<TEST_TIMES; i++){

????????????? memcpy(pstr + len, APPEND_CONTENT,strlen(APPEND_CONTENT));

????????????? len += strlen(APPEND_CONTENT);

?????? }

?????? END_AND_PRINT_TICK("Clanguage memcpy append");

?????? cout << "stringlength: " << strlen(pstr) << endl;

?

?????? //Cleanup

?????? free(pstr);

?????? pstr = NULL;

}

?

void test_mfc_cstring_append()

{

?????? CString str;

?

?????? BEGIN_TICK();

?????? for (int i=0; i<TEST_TIMES; i++){

????????????? str.Append(APPEND_CONTENT);

?????? }

?????? END_AND_PRINT_TICK("MFCCString append");

?????? cout << "stringlength: " << str.GetLength() << endl;

}

?

void test_mfc_cstring_append_operator()

{

?????? CString str;

??????

?????? BEGIN_TICK();

?????? for (int i=0; i<TEST_TIMES; i++){

????????????? str += APPEND_CONTENT;

?????? }

?????? END_AND_PRINT_TICK("MFCCString operator append");

?????? cout << "stringlength: " << str.GetLength() << endl;

}

?

int _tmain(int argc, _TCHAR* argv[])

{

#ifdef _DEBUG

?????? cout<< "DEBUG version." << endl;

#else

?????? cout << "Releaseversion." << endl;

#endif

?????? cout << "TEST_TIME:" << TEST_TIMES << endl;

?

?????? test_c_memcpy_append();

?????? test_stdstring_append_operator();

?????? test_stdstring_append();

?????? test_stdostringstream();

?????? test_stdstring_append_operator_preallocate();

?????? test_mfc_cstring_append();

?????? test_mfc_cstring_append_operator();

?????? test_c_strcat_append();

?????? PRINT_SORT_TEST_TICKS();

??????

?????? return 0;

}

?请接下部。。。

//这句是为了清楚当前的环境对下面的测试的影响,保留只是为了使测试更加的准确
str=null;System.gc();
//StringBuffer
start = System.nanoTime();
//构造函数中的参数如果等于整个结果的长度,那么速度将达到最快!
StringBuffer strBuffer = new StringBuffer( TEST_TIMES*7 );
for (int i=0; i<TEST_TIMES; i++){strBuffer.append("cppmule");}
long strBufferUsed = System.nanoTime() - start;
System.out.println("StringBuffer append: " + strBufferUsed/1000000f + " ms.");
//这句是为了清楚当前的环境对下面的测试的影响,保留只是为了使测试更加的准确
strBuffer.delete(0, strBuffer.length() );strBuffer = null;System.gc();
//StringBuilder
start = System.nanoTime();
StringBuilder strBuilder = new StringBuilder( TEST_TIMES*7 );
for (int i=0; i<TEST_TIMES; i++){strBuilder.append("cppmule");}
long strBuilderUsed = System.nanoTime() - start;
System.out.println("StringBuilder append: " + strBuilderUsed/1000000f + " ms.");

System.out.println("Times: " + TEST_TIMES);
}

public static void main(String[] args) {
testJavaStringPerformance2();
}
在java中,其实,还有更加快的字符串拼接方法:就是自己靠char[]来组装。StringBuidler的实现原理也就是这样实现的。

读书人网 >C++

热点推荐