【问题标题】:Java code efficiency when converting string [duplicate]转换字符串时的Java代码效率[重复]
【发布时间】:2021-03-14 05:42:41
【问题描述】:

我已经反编译了一个由第 3 方开发团队提供的修复程序。

这是原始代码:

if (this.getPassword() != null) {
    this.uid = this.getUserName();
    password = this.getPassword();
}
if (this.host != null) {
    en.put("hostname", this.host);
    if (password != null && password.toString().trim().length() != 0) {
        en.put("password", password.toString());
    }
    if (this.uid != null && this.uid.trim().length() != 0) {
        en.put("userID", this.uid);
    }
}

这是解决方法:

if (this.getPassword() != null) {
    this.uid = this.getUserName();
    final char[] passwordTemp = this.getPassword();
    password = new char[passwordTemp.length];
    for (int i = 0; i < passwordTemp.length; ++i) {
        password[i] = passwordTemp[i];
    }
}

if (this.host != null) {
    en.put("hostname", this.host);
    if (password != null && password.toString().trim().length() != 0) {
        en.put("password", new String(password));
    }
    if (this.uid != null && this.uid.trim().length() != 0) {
        en.put("userID", this.uid);
    }
}

这似乎大大降低了代码的性能。有谁知道为什么会这样做?有没有更好的方法来做到这一点?

【问题讨论】:

  • 查看链接问题。他们使用char[] 而不是String 作为密码。但是,它们的实现很差,因为密码稍后仍会转换为字符串:))
  • 我假设this.getPassword() 返回的数组中的字符在某个时候被删除了,而在其他地方仍然需要它。因此他们将密码复制到另一个不会被破坏的数组中。
  • 作为参考密码类型为:char[] password = null;
  • 看了你的代码后,我不得不承认我很困惑。如果passwordchar[],那么在它上面调用toString 是毫无意义的,你不会得到数组中字符的字符串表示形式。
  • 更改后您是否对应用程序进行了概要分析?瓶颈真的在您怀疑的代码 sn-p 中吗?我已经学会了关于性能问题的推测几乎总是失败的艰难方法。

标签: java string performance


【解决方案1】:

他们在这里所做的是复制密码数组。可能的原因:他们希望确保原始对象中的密码不被更改。在早期版本中,他们将对密码数组的引用泄漏到代码的某些部分,他们可能会或可能不会更改密码。

要么存在密码被更改但不应该更改的真正错误,要么他们只是想确保以后不会发生这种错误。

请注意,如果他们使用字符串而不是 char 数组,他们就不需要这个,因为字符串(意味着)是不可变的。

【讨论】:

    【解决方案2】:

    除了早点进行检查之外,我没有看到显着的性能改进。

    以下只是更好的风格:

                password = new char[passwordTemp.length];   
                for (int i = 0; i < passwordTemp.length; ++i) { 
                    password[i] = passwordTemp[i];  
                }   
    

    可以写成:

                password = Arrays.copyOf(passwordTemp, passwordTemp.length);
    

    它可能会提高性能,因为 JIT 可能有更多理由编译 copyOf

    在新的 Java 版本 11 中,可以使用 isBlank。旧代码中仍然存在问题。密码检查已修整(不是数组的 toString),并可能修整存储它以防止出现问题。

            if (password != null && new String(password).trim().isEmpty()) { 
                en.put("password", new String(password));   
            }   
    

    使用 isBlank:

            if (password != null && !new String(password).isBlank()) { 
                en.put("password", new String(password).trim());   
            }   
    

    (可以优化两个新的。)

    理想情况下,映射中的条目应该是char[],而映射中的可选en 是不幸的。但那不是你的代码。

    对于安全相关性(SonarQube、安全检查),您可以在最后做:

    ...
    en.put("password", "");
    Arrays.fill(password, ' ');
    

    【讨论】:

      猜你喜欢
      • 2012-12-10
      • 2012-02-02
      • 2017-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-12
      • 1970-01-01
      • 2016-11-23
      相关资源
      最近更新 更多