c语言 string_String、StringBuiler、StringBuffer,谁性能最高?

作者:Yuchao Huang

来源:www.cnblogs.com/misterchaos/p/12782986.html

一、前言

刚开始学习Java时,作为只会C语言的小白,就为其中的字符串操作而感到震撼。

相比之下,C语言在字节数组中保存一个结尾的\0去表示字符串,想实现字符串拼接,还需要调用strcpy库函数或者自己手动去复制数组,非常麻烦,更别提其他复杂操作。

而Java通过String类让字符串操作变得十分简单和方便。除此之外,还有stringbuilder等这些类的辅助,那么本文就String,StringBuiler和StringBuffer的区别开始,去探讨Java中的字符串操作

二、String,StringBuiler和StringBuffer

2.1 String类

Java 提供了 String 类来创建和操作字符串。关注公众号Java技术栈回复面试获取系列面试题。

在源码中可以看到,String类内部的实现也是一个字节数组,这个数组是final类型的,因此String是不可变的对象,每次在对String类进行改变的时候都会生成一个新的string对象,然后将指针指向新的string对象。

推荐阅读《5 个刁钻的 String 面试题!》

2.2 StringBuiler 类

和 String 类不同的是,StringBuilder 类的对象能够被多次的修改,并且不产生新的对象

这个特性的意义在于,如果我们进行大量的字符串操作,使用String类就会产生很大的性能消耗,而StringBuilder就可以避免这个问题。

2.3 StringBuffer 类

StringBuffer 和StringBuiler之间的最大不同在于 StringBuilder 的方法不是线程安全的

由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

2.4 String,StringBuiler和StringBuffer的比较(对比C/C++)

faafe47125f53487a36030e2e543fff0.png

三、各种字符串操作的效率测试

3.1 测试代码

@Test
public void test() {
    int count = 100000;

    long startTime = System.currentTimeMillis();
    String str = "";
    for(int i = 0; i        str += i;
    }
    System.out.println("执行"+count+"次  String 耗时:"+ getRunTime(startTime));

    startTime = System.currentTimeMillis();
    StringBuilder stringBuilder = new StringBuilder("");
    for (int i = 0; i         stringBuilder.append(i);
    }
    System.out.println("执行"+count+"次  StringBuilder 耗时:"+ getRunTime(startTime));

    startTime = System.currentTimeMillis();
    StringBuffer stringBuffer = new StringBuffer("");
    for (int i = 0; i         stringBuffer.append(i);
    }
    System.out.println("执行"+count+"次  StringBuffer 耗时:"+ getRunTime(startTime));

}

3.2 测试结果

执行100000次  String 耗时:32s
执行100000次  StringBuilder 耗时:2ms
执行100000次  StringBuffer 耗时:4ms

3.3 小结

可以看到String类的性能远低于StringBuiler和StringBuffer,而StringBuiler在本次测试中比Stringbuffer提高了50%的性能

四、Java字符串和正则表达式

4.1 测试代码

@Test
public void test0(){
    //邮政编码
    String postCode = "[1-9]\\d{5}";
    //区号-座机号码
    String areaCode = "\\d{3}-\\d{8}|\\d{4}-\\d{7}";
    //手机号码
    String phone = "(?:13\\d|15\\d|18\\d)\\d{5}(\\d{3}|\\*{3})";

    String text = "邮政编码:440834"+
                  "区号-座机号码: 020-12345678"+
                  "手机号:13536373839"+
                  "邮政编码:440833"+
                  "区号-座机号码: 010-12345678"+
                  "手机号:13536373739";

    Pattern p = Pattern.compile(postCode);
    Matcher m = p.matcher(text);
    System.out.println("文本中包含邮政编码:");
    while (m.find()){
        System.out.println(m.group());
    }

    p = Pattern.compile(areaCode);
    m= p.matcher(text);
    System.out.println("文本中包含区号-座机号码:");
    while (m.find()){
        System.out.println(m.group());
    }

    p = Pattern.compile(phone);
    m= p.matcher(text);
    System.out.println("文本中包含手机号:");
    while (m.find()){
        System.out.println(m.group());
    }
}

4.2 测试结果

文本中包含邮政编码:
440834
123456
135363
440833
123456
135363
文本中包含区号-座机号码:
020-12345678
010-12345678
文本中包含手机号:
13536373839
13536373739

五、总结

经过测试和比较,可以看到Java中同为字符串操作,但由于背后实现的原理不同,形成的性能差异也是十分巨大,相比之下,C/C++中的字符串操作性能更高。

String类的性能远低于StringBuiler和StringBuffer,而StringBuiler比Stringbuffer的性能稍微高一点。对性能的探究,最终还是要回到使用场景。

可以总结得出,如果不涉及字符串操作,那么String类是首选,如果涉及的字符串操作没有线程安全问题,那么使用StringBuilder,如果涉及的字符串操作存在线程安全问题,那么使用StringBuffer

----------  END  ----------

重磅!后厂技术官-技术交流群已成立扫码可添加后厂技术官助手,可申请加入后厂技术官大群和细分方向群,细分方向已涵盖:Java、Python、机器学习、大数据、人工智能等群。一定要备注:开发方向+地点+学校/公司+昵称(如Java开发+北京+快手+阿信),根据格式备注,可更快被通过且邀请进群18a55e13d15b1c7888c3e759a00acd7f.png▲长按加群

推荐阅读

• 内部泄露版!互联网大厂的最新薪资和职级一览

• 今日头条、抖音推荐算法原理全文详解!

• 人人网惨遭全网下架,但是我并不同情他!

• 再见!北京!再见!百度!

• 牛逼!北京后厂村惊现互联网工厂,007. ICU

推荐一个技术号

Github实验室,由国内一线大厂专家、985博士、硕士组成的团体运营。主要分享和研究业界实用、有趣的开源项目,学习资源,开发工具,学术交流。

关注就无套路送你一份5000页Java面试最强合集PDF。

dd6d58ee233d6a576a470b2ba1754bdd.png

最近面试BAT,整理一份面试资料大厂Java面试通关指北,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 BAT 领取,更多内容陆续奉上。
如有收获,点个在看,诚挚感谢7142b13aabc153be5923b75d87bcc750.png明天见(。・ω・。)ノ♡
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值