浅析C#/Java程序中字符串操作的性能问题。

简介: 在C#等面向对象语言中,虽然String是引用类型,但和普通的引用类型相关还是有较大的特殊型的。主要体现在两点:string中只有两个只读的属性,没有可设置的属性,所以说string 类型的实例具有固定不变性。

在C#等面向对象语言中,虽然String是引用类型,但和普通的引用类型相关还是有较大的特殊型的。主要体现在两点:

  1. string中只有两个只读的属性,没有可设置的属性,所以说string 类型的实例具有固定不变性。只要是改变了字符串的内容,系统就会在堆内存中生成一个全新的字符串。其实这一点并不能算作是字符串的特殊性,这和普通的引用类型没什么区别,只是string类型在定义的时候,没有创建可以写的属性,所以这只能算作是字符串的一般特性。
  2. 字符串中驻留池的概念,这是string类型特有的,所以这是字符串的特殊性。当我们声明的字符串和堆中已存在的某个字符串的值一样时,不会再在堆中开辟空间,创建新的实例,而是将当前声明字符串的引用指向已经存在的实例。
    在我们进行多个string操作的时候,是直接使用+运算符还是使用其它的,看看下面的例子就知道你应该使用使用了。
        static void TestAdd(int counts)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            string str = "";
            for(int i = 0; i < counts; i++)
            {
                str = str + addStr ;
            }
            sw.Stop();
            Console.WriteLine($"Using add time is : {sw.Elapsed.Hours}:{sw.Elapsed.Minutes}:{sw.Elapsed.Seconds}  {sw.Elapsed.Milliseconds}");
        }

        static void TestSb(int counts)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < counts; i++)
            {
                sb.Append(addStr);
            }
            string str = sb.ToString();
            sw.Stop();
            Console.WriteLine($"Using SB time is : {sw.Elapsed.Hours}:{sw.Elapsed.Minutes}:{sw.Elapsed.Seconds}  {sw.Elapsed.Milliseconds}");
        }
        static void TestList(int counts)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            List<string> ls = new List<string>();
            for (int i = 0; i < counts; i++)
            {
                ls.Add(addStr);
            }
            string str = string.Join("", ls);
            sw.Stop();
            Console.WriteLine($"Using List time is : {sw.Elapsed.Hours}:{sw.Elapsed.Minutes}:{sw.Elapsed.Seconds}  {sw.Elapsed.Milliseconds}");
        }

各次运行结果如下:
2019_06_26_11_12_56
2019_06_26_11_12_09
2019_06_26_11_11_18
2019_06_26_11_09_55
我们可以看到,当有十万次的操作时,+运行时间达到了7分钟还多,而StringBuilder仅仅用了25毫秒,性能的差异是如此的巨大。
如果在你的程序中对于String类型该如何操作你心里是否有打算了。

目录
相关文章
|
人工智能 监控 安全
智慧工地解决方案,java智慧工地程序代码
智慧工地系统融合物联网、AI、大数据等技术,实现对施工现场“人、机、料、法、环”的全面智能监控与管理,提升安全、效率与决策水平。
394 2
|
安全 Java
Java异常处理:程序世界的“交通规则
Java异常处理:程序世界的“交通规则
458 98
|
SQL JSON Java
告别字符串拼接:用Java文本块优雅处理多行字符串
告别字符串拼接:用Java文本块优雅处理多行字符串
684 108
|
SQL JSON Java
告别拼接噩梦:Java文本块让多行字符串更优雅
告别拼接噩梦:Java文本块让多行字符串更优雅
1084 82
|
存储 机器学习/深度学习 监控
网络管理监控软件的 C# 区间树性能阈值查询算法
针对网络管理监控软件的高效区间查询需求,本文提出基于区间树的优化方案。传统线性遍历效率低,10万条数据查询超800ms,难以满足实时性要求。区间树以平衡二叉搜索树结构,结合节点最大值剪枝策略,将查询复杂度从O(N)降至O(logN+K),显著提升性能。通过C#实现,支持按指标类型分组建树、增量插入与多维度联合查询,在10万记录下查询耗时仅约2.8ms,内存占用降低35%。测试表明,该方案有效解决高负载场景下的响应延迟问题,助力管理员快速定位异常设备,提升运维效率与系统稳定性。
506 4
|
自然语言处理 Java Apache
在Java中将String字符串转换为算术表达式并计算
具体的实现逻辑需要填写在 `Tokenizer`和 `ExpressionParser`类中,这里只提供了大概的框架。在实际实现时 `Tokenizer`应该提供分词逻辑,把输入的字符串转换成Token序列。而 `ExpressionParser`应当通过递归下降的方式依次解析
604 14
|
存储 Java 编译器
对比Java学习Go——程序结构与变量
本节对比了Java与Go语言的基础结构,包括“Hello, World!”程序、代码组织方式、入口函数定义、基本数据类型及变量声明方式。Java强调严格的面向对象结构,所有代码需置于类中,入口方法需严格符合`public static void main(String[] args)`格式;而Go语言结构更简洁,使用包和函数组织代码,入口函数为`func main()`。两种语言在变量声明、常量定义、类型系统等方面也存在显著差异,体现了各自的设计哲学。
437 0
|
存储 SQL 数据库连接
C#程序调用Sql Server存储过程异常处理:调用存储过程后不返回、不抛异常的解决方案
本文分析了C#程序操作Sql Server数据库时偶发的不返回、不抛异常问题,并提出了解决思路。首先解析了一个执行存储过程的函数`ExecuteProcedure`,其功能是调用存储过程并返回影响行数。针对代码执行被阻塞但无异常的情况,文章总结了可能原因,如死锁、无限循环或网络问题等。随后提供了多种解决方案:1) 增加日志定位问题;2) 使用异步操作提升响应性;3) 设置超时机制避免阻塞;4) 利用线程池分离主线程;5) 通过信号量同步线程;6) 监控数据库连接状态确保可用性。这些方法可有效应对数据库操作中的潜在问题,保障程序稳定性。
1059 11