`
cppmule
  • 浏览: 447042 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

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

阅读更多

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

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

字符串拼接测试方式分别是:

1.  C语言在预分配内存上的strcpy函数

2.  C语言在预分配内存上的 memcpy函数

3.  C++std::stringappend函数

4.  C++std::string operator+=

5.  C++std::ostringstreamoperator<<

6.  C++std::string使用事先预分配(调用 reserve函数)

7.  MFCCStringAppend函数

8.  MFCCStringoperator+=

 

以下测试代码:

注:在 const int TEST_TIMES = 9000000;Cmemcpy使用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 << "sort order: " << order << endl   \

                                    << stat;                    \

              }                                               \

              int order;                                        \

       } printer;                                               \

cout << "---------Statistics informations(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::string append");

       cout << "string length: " << 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 << "string length: " << 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 << "string length: " << 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 << "string length: " << 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("hava resize(PREALLOCATE_SIZE) std::string += operator");

       cout << "string length: " << 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("c string function strcat:");

       cout << "string length: " << 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't allocate 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("C language memcpy append");

       cout << "string length: " << 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("MFC CString append");

       cout << "string length: " << 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("MFC CString operator append");

       cout << "string length: " << str.GetLength() << endl;

}

 

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

{

#ifdef _DEBUG

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

#else

       cout << "Release version." << 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;

}

 请接下部。。。

分享到:
评论
6 楼 form_rr 2011-02-27  
我的补充,详细的内容在注释中
public static void testJavaStringPerformance2() {
final int TEST_TIMES = 100000;
//String
String str = "";

System.out.println("The testing is running, please wait...");
// 使用纳秒作为时间计量单位,更加精确点
long start = System.nanoTime();
for (int i=0; i<TEST_TIMES; i++){str += "cppmule";}
long strUsed = System.nanoTime() - start;
System.out.println("strUsed: " + strUsed/1000000f + " ms.");
// 这句是为了清楚当前的环境对下面的测试的影响,保留只是为了使测试更加的准确
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的实现原理也就是这样实现的。
5 楼 cppmule 2011-01-21  
讲讲区别,我洗耳恭听
4 楼 kakueiken 2011-01-19  
楼主,以后《上传》压缩文件。用ZIP。别用RAR。
什么意思大家多知道的。
3 楼 cppmule 2011-01-10  
您好,帖子长度超过了论坛的限制,需要分发不过里面有文档,和源码。你可以下载。
文档时*.docx的
2 楼 cppmule 2011-01-10  
您好,帖子长度超过了论坛的限制,需要分发不过里面有文档,和源码。你可以下载。
文档时*.docx的
1 楼 苍山洱海 2011-01-09  
1,6,7,8的结果呢。
JAVA的呢。?

相关推荐

    C/C++ 字符串拼接 字符串 数组

    C/C++ 字符串拼接 字符串 数组

    二维码(QRcode)生成算法 C语言/C++源码

    #二维码(QRcode)生成算法 C语言/C++ 源码 1. 根据输入字符串识别编码模式; 2. 根据输入字符串长度选择合适的QRcode版本; 3. 将编码转换为二进制位流表示为数据码字; 4. 使用多项式生成纠错码; 5. 将数据码和...

    c/c++ 与java互通 AES加密解密,算法ECB

    工作原因c和java都得熟悉,因此把java端和c/c++实现都给大家了,注意java端要明确指明字符集为GBK,因为各版本jdk默认字符集并不一致,key采用16位,你知道的。压缩包里有两个工程,一个vc6.0一个myeclipse,本帖是...

    c / c++ / cpp / stl 中文帮助文档手册chm格式下载

    c / c++ / cpp / stl 中文帮助文档手册chm格式下载 C/C++ 语言参考 基本C/C++ 预处理命令 操作符优先级 转义字符 ASCII码表 基本数据类型 关键字 标准 C 库: Standard C I/O Standard C String...

    C/C++ API 帮助文档大全(中文,chm格式)

    C/C++ API 帮助文档大全是一份全面的资源,包含了C和C++编程语言的各类API接口和函数的详细信息。这份文档通常以CHM(Compiled Help Manual)格式存在,这是一种由微软开发的、用于存储HTML帮助文档的压缩格式。通过...

    C/C++中文文档(支持C++20和C18)和蓝桥杯C/C++组用的文档

    这个文档压缩包包含普通C/C++中文文档和蓝桥杯比赛时用的文档,C/C++中文文档是最新版,支持到C++20和C18,且包含以前版本的内容。蓝桥杯蓝桥杯C/C++组用的文档比正常文档更简略,但包含了ASCII码表。

    使用C++实现的字符串拼接函数的实现及讨论.docx

    c 字符串拼接C/C++中针对字符串函数的使用过程中,需要格外注意字符串终止符'\0'。字符串结尾处默认带'\0'。 带形参n的库函数可以有效防止因字符串长度过长导致的段错误,建议使用带n的字符串函数。一 、snprint数的...

    C/C++字符串,字符转数字,数字转字符

    C/C++语言本身并没有专门的字符串变量类型,而是使用字符数组来存放字符串,其中字符串的结束符是“\0”(空字符)。掌握字符与数字之间的转换对于进行有效编程至关重要,尤其在处理用户输入、数据输出以及与其他...

    C语言字符串函数大全C/C++基础 字符串操作大全

    根据提供的信息,我们可以详细探讨几个重要的C语言字符串处理函数,这些函数是进行字符串操作的基础工具。下面我们将逐一介绍这些函数的功能、用法以及提供具体的示例代码。 ### 1. stpcpy #### 功能 `stpcpy` 函数...

    格C/C++语言式化字符串

    例如,`%6.9s`表示显示长度不小于6且不大于9的字符串,如果超过9,则第9个字符之后的内容会被截断。 此外,`l`(小写L)可以用来指定长整型(`long`)或双精度浮点型(`double`),如`%ld`和`%lf`。 对齐方式可以...

    C/C++中文帮助文档

    C/C++参考手册是专为C语言开发者制作的一个学习文档,包含了基本的介绍、预处理命令、算法、正则表达式、转义字符、基本数据类型等介绍,可以方便开发者快速掌握C语言的开发技巧,让你轻松开发出满意的软件。

    c/c++ 与java互通 AES加密解密,算法ECB/PKCS5PADDING

    工作原因c和java都得熟悉,因此把java端和c/c++实现都给大家了,注意java端要明确指明字符集为GBK,因为各版本jdk默认字符集并不一致,key采用16位,你知道的。压缩包里有两个工程,一个vc6.0一个myeclipse,都拿去...

    基于C/C++及java开发的物联网智能婴儿床+源码+文档(毕业设计&课程设计&项目开发)

    基于C/C++及java开发的物联网智能婴儿床+源码+文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ 基于C/C++及java开发的物联网智能婴儿床+源码+文档,适合毕业...

    C/C++的split分隔字符串

    标准C/C++编写的字符串分隔函数,可以设置分隔字符串,解出字符串存到vector里面。有需要的可以下载

    C/C++实现字符串拆分

    C/C++实现字符串的拆分截取,输入一个字符串,并输入截取起始位置和截取长度,返回截取到的结果

    C语言/C++基础之爱心源码

    C语言/C++基础之爱心源码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    C语言/C++基础之冰墩墩源码

    C语言/C++基础之冰墩墩源码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    C++中英混合字符串截取

    在C++编程中,处理字符串是一项常见的任务,特别是在游戏开发客户端和服务器端的场景中。题目中的问题聚焦于如何正确地截取一个中英混合的字符串,确保在截取过程中不会将汉字字符截断。这个问题涉及到字符编码、...

Global site tag (gtag.js) - Google Analytics