我应该缓存System.getProperty(“line.separator”)吗?

考虑这样的方法:

@Override public String toString() { final StringBuilder sb = new StringBuilder(); for (final Room room : map) { sb.append(room.toString()); sb.append(System.getProperty("line.separator")); // THIS IS IMPORTANT } return sb.toString(); } 

System.getProperty("line.separator")可以多次调用。

我应该使用public final static String lineSeperator = System.getProperty("line.separator")缓存此值,以后只使用lineSeperator吗?

System.getProperty("line.separator")与使用静态字段一样快?

我认为你的问题是错误的二分法。 我不会每次都调用getProperty ,也不会为它声明静态字段。 我只是将它提取到toString的局部变量。

 @Override public String toString() { final StringBuilder sb = new StringBuilder(); final String newline = System.getProperty("line.separator"); for (final Room room : map) sb.append(room.toString()).append(newline); return sb.toString(); } 

顺便说一句,我已经对电话进行了基准测 代码:

 public class GetProperty { static char[] ary = new char[1]; @GenerateMicroBenchmark public void everyTime() { for (int i = 0; i < 100_000; i++) ary[0] = System.getProperty("line.separator").charAt(0); } @GenerateMicroBenchmark public void cache() { final char c = System.getProperty("line.separator").charAt(0); for (int i = 0; i < 100_000; i++) ary[0] = (char)(c | ary[0]); } } 

结果:

 Benchmark Mode Thr Cnt Sec Mean Mean error Units GetProperty.cache thrpt 1 3 5 10.318 0.223 ops/msec GetProperty.everyTime thrpt 1 3 5 0.055 0.000 ops/msec 

缓存方法的速度提高了两个多个数量级。

请注意, getProperty调用所有字符串构建的总体影响非常非常不太明显。

在代码运行时,您不必担心行分隔符会发生变化,因此我认为没有理由不对其进行缓存。

缓存值肯定比反复执行调用更快,但差异可能可以忽略不计。

既然这么容易,为什么不呢? 至少 System.getProperty()的实现必须进行哈希表查找(即使在内部缓存)以查找您请求的属性,然后将在生成的Object上调用虚方法getString() 。 这些都不是非常昂贵,但需要多次调用。 更不用说会创建很多String临时工具,之后需要GCing。

如果将其移到循环的顶部并重用相同的值,则可以避免所有这些问题。 为什么不呢?

如果您已经意识到您知道的与此相关的性能问题,是的。

如果你没有,那么不,查找不太可能有足够的开销。

这将属于“微优化”和“过早优化”的一般类别中的任何一个或两个。 🙂


但是如果你担心效率,你可能有更大的机会,因为你的toString方法每次都重新生成字符串。 如果toString将被调用很多,而不是缓存行终止符,缓存生成的字符串,并在房间地图发生变化时清除它。 例如:

 @Override public String toString() { if (cachedString == null) { final StringBuilder sb = new StringBuilder(); final String ls = System.getProperty("line.separator"); for (final Room room : map) { sb.append(room.toString()); sb.append(ls); } cachedString = sb.toString(); } return cachedString; } 

……当地图发生变化时,请执行此操作

 cachedString = null; 

对于降压来说,这是更大的收获 (降压是额外磁场的开销)。 虽然它是每个实例而不是每个类,所以(参考之前关于效率的评论)只有在你有充分理由的情况下才能这样做。

如果系统属性在应用程序期间保证保持不变,则可以对其进行高速缓存,但通常会丢失属性的function,这会在更改时改变行为。

例如,文本生成器可以使用该属性为Windows或Linux生成文本,并允许在应用程序中动态更改属性,为什么不呢?

通常,捕获属性意味着使函数setProperty变得无用。