用string和char*哪个更快,有实验,大家进来讨论一下。

flamingheart 2006-04-23 10:04:41
for(int i = 0; i < 100000000; i++)
{
char c[] = "china";
string str = c;
}

for(int i = 0; i < 100000000; i++)
{
char c[] = "china";
char* str = new char[7];
strcpy(str, c);
delete[] str;
}

上面两个for语句哪个更耗时?
在我机器上测:
第一个 :4.9s
第二个 : 23.1s

凭我的感觉正好应该相反阿,这是怎么回事?
...全文
1513 44 点赞 打赏 收藏 举报
写回复
44 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
pdcpccc 2006-05-20
如果把char *的new和delete去掉,减除那部分开销的话。。
string: 62390636993
char *: 7265354273
  • 打赏
  • 举报
回复
pdcpccc 2006-05-20
然而实践证明,string str 没有创建和销毁的开销(别怀疑,的确没有)

#include <string>
#include <iostream>
#include <stdio.h>

using namespace std;

__declspec(naked) unsigned long long rdtsc() {
__asm {
rdtsc
ret
}
}

int main() {
unsigned long long int ts;
unsigned long long int te;
unsigned long long int tl;
ts = rdtsc();
for(int i=0; i<100000000; i++) {
char c[] = "china";
string *str = new string(c);
delete str;
}
te = rdtsc();
tl = te - ts;
printf("string: %llu\n", tl);
ts = rdtsc();
for(int i=0; i<100000000; i++) {
char c[] = "china";
char *str = new char[7];
strcpy(str, c);
delete []str;
}
te = rdtsc();
tl = te - ts;
printf("char *: %llu\n", tl);
return 0;
}

这样的话,
F:\Dev\rdtsc>rdtsc
string: 150897241140
char *: 72596077792
  • 打赏
  • 举报
回复
pdcpccc 2006-05-20
F:\Dev\rdtsc>rdtsc
string: 60196780163
char *: 64480798658

事实上。。。
  • 打赏
  • 举报
回复
YFY 2006-05-19
来看看。

看用的人怎么用了。
  • 打赏
  • 举报
回复
cattlenzq 2006-05-19
不错不错,这个都挖出来了
  • 打赏
  • 举报
回复
code_tin 2006-05-15
其实不光是效率。内存占用等等也是需要考虑的问题
这就是C++至今没有被引入嵌入环境的原因
这种比较不光是表面的简单比较
还会引入许多诸如编译原理,汇编,编译器实现等等相关内容
我觉得这样的讨论是很有益处的。
不能简单的就说应该一直使用string
也同样不能简单的就说char比string来的快。
  • 打赏
  • 举报
回复
flamingheart 2006-05-15
楼上的兄弟,有的时候效率是不得不考虑的因素。
  • 打赏
  • 举报
回复
塘外人 2006-05-15
难道string的效率就那么慢吗/?/?/?/?/?/?/?/?/?/?
  • 打赏
  • 举报
回复
Muf 2006-05-15
string的实现是COW的。
  • 打赏
  • 举报
回复
hearing 2006-05-15
ZZ一位高人的看法

存取效率的比较

char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
#include <stdio.h>
void main()
{
char a = 1;
char c[] = "1234567890";
char *p ="1234567890";
a = c[1];
a = p[1];
return;
}
对应的汇编代码
10: a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。


针对LZ的问题,除去由于使用的编译器不同而造成的区别外,应该是使用数组比使用指针可以获得更高的效率
  • 打赏
  • 举报
回复
aronzhou 2006-05-15
看一下汇编代码不就什么都解决了?
  • 打赏
  • 举报
回复
塘外人 2006-05-10
这种比较有什么意思? 没有

看看代码吧,
简单就是美

难道在允许使用string的时候还要犹豫吗?
  • 打赏
  • 举报
回复
delphihero 2006-05-10
sizeof(string)一般大于14; 里面有成员变量。
vc 的 string 没有引用技术,随便调试一下就知道了。 string str1="123";string str2=str1;
很明显他们的缓冲区地址不同。
微软的CString 使用了引用计数。CString str1="123";CString str2=str1;
里面缓冲区指向了相同的地址。如果使用 CString做楼主的例子也差不多。
dev不知道什么版本stl,使用了引用计数
但不管CString 也好,dev 也好对于
char c[] = "china";
string str = c;
是没有什么引用计数的, 只有 string 之间赋值才会使用引用计数.
如果使用release 版本测试编译器回开你玩笑的
搂主的结果跟我在vc2003 里的 release 版查不多。string 快是因为 string 被优化在循环外面
在栈上面已经定义了这个变量。而且在加上初始了一定的空间。相当于第二个程序没有了 new 和delete 操作.对应情况可以同过反汇编调出来
  • 打赏
  • 举报
回复
mhisky 2006-05-10
mark
  • 打赏
  • 举报
回复
code_tin 2006-04-25
char c[] = "china";
string str = c;

这个问题在effective c++里面有提到
C++对这个情况有优化的
  • 打赏
  • 举报
回复
flamingheart 2006-04-25
太好了,大家说得都非常好,我总结了一下,现在大体有几种观点:
1。string str = c;被编译器优化掉了。
2。使用的标准库的版本有关,string str = c; -> 使用STL自己的allocator 这个allocator有自己的memory pool。
3。string应该是有预留空间,对于较小的字符串不需要每一次都重新分配空间。

根据以上观点,我又做了几个实验:
实验0。(主题贴的试验)7个字符,release版:
string版:4.9s,char*版:23.1s
实验1。120个字符,release版:
string版:44.6s,char*版:45.9s
实验2。7个字符,debug版:
string版:104.4s,char*版:62.3s

我分析如下:
如果是被编译器优化掉了的话,那为什么增长到120个字符,string版会上升到44.6s呢,但是凭感觉的话,string str = c;应该被优化掉啊,大家再讨论讨论。
  • 打赏
  • 举报
回复
healer_kx 2006-04-25
从算法哲学上讲,显然string要快很多了。
人家用空间换得了时间啊。

sizeof(string)一般大于14;

比如说就简单的字符串长度,string就是常数时间o(1),而char*就要o(n)

再比如前面大家都提到的内存池。这个显然会提高效率嘛。

至于引用计数那个观点,不同的STL版本是不一样的实现,用不用都有性能得失,但是总得来说都提高了性能或者线程安全。
目前倾向于无引用计数的版本,因为malloc提速了。
  • 打赏
  • 举报
回复
nicenight 2006-04-25
第一个循环只是纯粹的声明嘛,C++与C的不同之处就是C++可以在任何地方做声明,因为C++编译器在做编译时会先扫描一遍程序,把所有的声明都归到一起。这样,其实这个循环就没有做什么东西了,速度就自然是快了。而第二个,申请和释放内存这就不用说了。
  • 打赏
  • 举报
回复
Jinhao 2006-04-25
这个和你使用的标准库的版本有关

char* str = new char[7];

string str = c; -> 使用STL自己的allocator 这个allocator有自己的memory pool,也许在上面的循环中只有一次向操作系统申请内存
  • 打赏
  • 举报
回复
sharpdew 2006-04-24
针对你的程序而言,一个是STL为你管理内存,一个是你自己管理内存,这就是差别!
  • 打赏
  • 举报
回复
加载更多回复
相关推荐
发帖
C++ 语言
加入

6.0w+

社区成员

C++ 语言相关问题讨论,技术干货分享,前沿动态等
申请成为版主
帖子事件
创建了帖子
2006-04-23 10:04
社区公告
暂无公告