【问题标题】:StringBuilder - setLength(0) vs new instantiate, what is better?StringBuilder - setLength(0) 与新实例化,哪个更好?
【发布时间】:2020-01-08 13:34:58
【问题描述】:

我有一个循环(当我从蓝牙接收到数据时,每次迭代重复 2 次),我使用 StringBuilder 单独附加数据,在最终过程中我需要 清除 StringBuilder obj,

我现在正在使用新的实例化,但是,我已经使用了.setLength 方法,这比.setLength 或新的实例化更好?

从蓝牙设备接收数据的代码示例:

 private void receive(byte[] data) {
     peso.append(new String(data));
     receiveText.setText(peso.toString().replaceAll("(\\r|\\n)", "")+" Kg"); 
     // int i = Integer.parseInt(peso.toString().replaceAll(("\\r|\\n"), ""));
     Log.i("Val of append actual", String.valueOf(peso));

     if(peso.length() >= 3) 
         peso = new StringBuilder();

 }

其他细节: 我知道我的“比索”的最大尺寸,这对选择有帮助吗?

【问题讨论】:

  • 为了清楚起见,您能否分享一下您正在执行此操作的代码。
  • 您不太可能看到任何显着差异。将变量保持在一个小范围内并创建一个新对象可以正常工作并且不会提供任何惊喜。使用 setLength(0) 不会给您带来任何性能优势,但您的代码最终可能看起来“更奇怪”。
  • 您可以edit您的帖子并添加minimal reproducible example
  • OP 清楚地知道副本解决了哪些问题。这个问题是关于它以哪种方式完成是否重要(它很可能不重要)。
  • 对不起,我现在添加代码,谢谢大家!

标签: java android performance stringbuilder


【解决方案1】:

我不确定您的用例。但无论如何,新实例化总是一个不错的选择,而不是将长度设置为零,它显示了更好的代码意图,因为您的代码将更易于理解和可读。

性能差异确实可以忽略不计,但您的代码会更简单。

【讨论】:

  • “但是你的代码会更短更简单”...你能添加一个例子来帮助我理解吗?
  • 我应该使用“仅简单”这个词,但无论如何 sb.setLength(0);或 sb.delete(0, sb.length());没有描述代码的真实意图。我们使用 StringBuilder v = new StringBuilder(); 更好的可读性
【解决方案2】:

实例化可能会很慢,因为创建新对象需要时间,但从 StringBuilder 中删除内容不需要为其内部数组分配内存,这使得该过程更好更快。

【讨论】:

    【解决方案3】:

    我什至读到new StringBuilder 在一个实例中更快。 所以这或多或少是一个无关紧要的微优化。根据您的情况对其进行分析。 我会给出一个初始容量:new StringBuilder(64)

    备注:

    • 目前if (peso.length() >= 3) 可能用于测试。
    • 指定data 字节的字符集。最佳 StandardCharsets.UTF_8。
    • 日志记录很慢;删除它。
    • 正则表达式很慢。下面是非正则表达式替换。
    • \R 用于任何换行符,\n、\r\n、\r、NEL。

    所以:

     private void receive(byte[] data) {
         peso.append(new String(data, StandardCharsets.ISO_8859_1));
         String pesoS = peso.toString();
         //receiveText.setText(pesoS.replaceAll("\\R", "")+" Kg");
         receiveText.setText(pesoS.replace("\r", "").replace("\n", "")+" Kg"); 
         Log.i("Val of append actual", pesoS);
    
         if (peso.length() >= 3) 
             peso = new StringBuilder(16);
     }
    

    【讨论】:

    • 应用程序完成后我会删除日志,这是调试版本,感谢您的提示!
    • 一个好奇心,为什么需要指定字符集?
    • 如果没有显式参数,则使用默认平台编码。对于跨平台数据(您提供的文件、远程数据;网络/数据库),保证创建一个不可移植(=错误)的应用程序。所以那将是臭代码。甚至使用Charset.getDefaultCharset() 明确表明您使用的是本地数据。
    • 我将添加 UTF-8,因为我需要从 Arduino(使用蓝牙)接收数据并将数据发送到 Firebase 数据库。谢谢
    • “正则表达式很慢。” 事实上,主要的开销是解析。使用预解析的正则表达式几乎与固定字符串搜索一样高效。
    猜你喜欢
    • 2014-03-05
    • 2010-10-09
    • 2016-12-15
    • 2012-11-07
    • 1970-01-01
    • 2012-06-09
    • 2016-05-18
    相关资源
    最近更新 更多