现有的StringBuilder“智能”初始容量解决方案

5

我有一段与日志和跟踪相关的代码,经常在整个代码中调用,特别是在追踪打开时。使用StringBuilder构建字符串。我认为字符串具有合理的最大长度,大约在几百个字符左右。

问题:是否存在现有库来执行类似于此的操作:

// in reality, StringBuilder is final,
// would have to create delegated version instead,
// which is quite a big class because of all the append() overloads
public class SmarterBuilder extends StringBuilder {         

    private final AtomicInteger capRef;

    SmarterBuilder(AtomicInteger capRef) {
        int len = capRef.get(); 
        // optionally save memory with expense of worst-case resizes:
        // len = len * 3 / 4;
        super(len);
        this.capRef = capRef;
    }

    public syncCap() {
        // call when string is fully built
        int cap;
        do {
            cap = capRef.get();
            if (cap >= length()) break;
        } while (!capRef.compareAndSet(cap, length());
    }
}
为了利用这一点,我的与日志相关的类将具有适当范围的共享capRef变量。 (奖励问题:我很好奇,是否可以在不使用循环的情况下进行syncCap()?) 动机:我知道StringBuilder的默认长度总是太小。我可以(并且目前确实这样做)投入一个100的临时容量值,这会导致某些情况下需要调整大小,但不总是。然而,我不喜欢源代码中出现神奇数字,而且这个特性是“优化一次,在每个项目中使用”的情况。
2个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
1

确保进行性能测量,以确保您真正从额外的工作中获得了一些好处。

作为 StringBuilder 类的替代方案,请考虑使用 StringBuilderFactory。它可以提供两个静态方法,一个用于获取 StringBuilder,另一个在构建字符串完成时调用。您可以将 StringBuilder 作为参数传递给它,并记录其长度。getStringBuilder 方法将使用其他方法记录的统计信息来选择初始大小。

有两种方法可以避免在 syncCap 中循环:

  1. 同步。
  2. 忽略失败。

在这种情况下忽略失败的论点是,您只需要实际长度的随机抽样。如果另一个线程正在更新,您仍然会得到最新的字符串长度视图。


我最终创建了一个微不足道的内部工厂类,其中包含get()和update()方法以及针对该特定情况的正确假设。 - hyde

0
你可以在一个统计数组中存储每个字符串的长度。运行你的应用程序,在关闭时取出字符串长度的90%分位数(对所有字符串长度值进行排序,并在数组位置上取长度值= sortedStrings.size() * 0.9)。 这样,你就创建了一个初始的字符串构建器大小,其中90%的字符串将适合其中。 更新: 该值可以硬编码(像Java在ArrayList中使用值10一样),或者从配置文件中读取,或者在测试阶段自动计算。但是四分位数计算不是免费的,所以最好在项目运行一段时间后,在SmartBuilder内部实时测量90%分位数,输出90%分位数,然后稍后更改属性文件以使用该值。 这样,你就可以为每个项目获得最佳结果。 或者更进一步:让你的智能构建器定期更新配置文件中的该值。 但是,这一切都不值得努力,你只会为具有数百万条目的数据(如数字路线图等)做这些事情。

如果我理解你的意思正确,你的意思是这是一种通过硬编码到源代码中获得良好价值的方法?是的,但我正在寻找一种自动执行它的方法。在整个项目中,优化非常小,因此没有必要花费时间在优化几个硬编码值上(在同一项目的不同部分,不同项目中),特别是当最佳值可能随着下一个代码更改而改变时。优化必须是“免费”的(或者至少非常便宜,例如向代码添加一个额外的AtomicInteger)。 - hyde

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,