节约用电小贴士
容器越来越小。 我们的编程需要转移以进行补偿。
我们曾经能够编写要在具有大量内存和大量CPU的大型计算机上运行的代码。 然后出现了云计算,计算机虽然大小适中,但并不庞大。
然后出现了容器化,我们开始在四分之一的CPU和很少的系统RAM上运行我们的软件。

企业软件开发人员必须掌握与嵌入式或游戏软件开发人员相同的挑战。
我们必须完善资源利用的艺术
正如我之前关于CI 所写的那样,计算任务的效率具有绿色影响。 就服务器场而言,绿色代表着地球变热并燃烧着能源,而就美元(或其他任何方面)而言,绿色代表着不被浪费,因为您必须在更多节点上运行环境。
最重要的是,您可能希望您的应用以最高速度运行。
计算机程序使用CPU周期来计算事物并消耗系统内存。 任务结束后,必须回收系统内存,这会导致更多的CPU使用率。 同样,当任务占用大量系统内存时,也会涉及工作量和风险。 分配方面的努力,以及在系统内存不足/内存不足时出现速度变慢或停止的风险。
了解你的敌人
临时堆对象不是敌人。 不必要的是。
考虑以下算法:
private static final String PAIR_PATTERN = "(?<=\\G.{2})" ; public static String hexToString(String hex) {
if (StringUtils.isBlank(hex) ||
hex.length() % 2 != 0 ) {
throw new RuntimeException( "Invalid input" );
}
List<Byte> list = Arrays.stream(hex.split(PAIR_PATTERN))
.map(convertStringToByte())
.collect(Collectors.toList());
return new String(ArrayUtils.toPrimitive(
list.toArray( new Byte[list.size()])),
StandardCharsets.ISO_8859_1); } private static Function<String, Byte> convertStringToByte() {
return s -> Integer.valueOf(Integer.parseInt(s, 16 ))
.byteValue(); }
这是一个十六进制到字符串的转换器。 也许从图书馆借书会更有效。 也许这是一个好主意,因为它使用了我们想要的编码等等。
关于上述问题,这有多节俭!?
不是特别的…
上面是慢速或内存浪费技术的购物清单。 API和Java类型系统允许我们使用它们的方式吸引了我们。 不过,值得使用这个无辜的例子来学习一些经验教训。 这是其中注释了所有不成比例的资源使用情况的代码:
// splitting a string with a regex and when you just want // pairs is probably overkill, compared with repeated // use of substring private static final String PAIR_PATTERN = "(?<=\\G.{2})" ; public static String hexToString(String hex) {
if (StringUtils.isBlank(hex) ||
hex.length() % 2 != 0 ) {
throw new RuntimeException( "Invalid input" );
}
// we're using streaming and a variable-sized list
// when we know the target size - variable sized
// structures come with overheads
List<Byte> list = Arrays.stream(hex.split(PAIR_PATTERN))
// we're mapping using a function that
// creates a function not a huge overhead,
// but a bit of a surprise
.map(convertStringToByte())
.collect(Collectors.toList());
// this line is the shocker
// the new Byte[list.size()] is a misuse of the API
// which only needs ANY byte array, as it will create
// its own to return - so there's a whole wasted array
// the array itself being of the wrong type - Byte
// rather than byte, so it's immediately replaced by
// another array with the unboxed values
return new String(ArrayUtils.toPrimitive(
list.toArray( new Byte[list.size()])),
StandardCharsets.ISO_8859_1); } private static Function<String, Byte> convertStringToByte() {
// the boxing of the integer only to
// convert it to a Byte is an
// extra object and operation
return s -> Integer.valueOf(Integer.parseInt(s, 16 ))
.byteValue(); }
替代
认真…使用图书馆。 虽然:
public static String hexToString(String hex) {
if (StringUtils.isBlank(hex) ||
hex.length() % 2 != 0 ) {
throw new RuntimeException( "Invalid input" );
}
byte [] hexToBytes = new byte [hex / 2 ];
int writeIndex = 0 ;
for ( int i = 0 ; i < hex.length(); i += 2 ) {
hexToBytes[writeIndex++] =
stringToByte(hex.subString(i, i + 2 ));
}
return new String(hexToBytes,
StandardCharsets.ISO_8859_1); } private static byte stringToByte(String hex) {
return ( byte )(Integer.parseInt(hex, 16 )); }
也可以。 假设通过某种智能运行时内联以某种方式自动处理了调用stringToByte
的开销。
这种方法优于其他方法的地方是它分配了固定大小的缓冲区并重新使用它。 我们以前在C ++中使用的方式!
结论
我们需要使用尽可能少的资源。 我们可能仍然可以依靠计算机的速度如此之快,以至于不作一般性的优化就便宜了,总的来说,宁愿使用可读的代码也要花费数小时的艰苦优化。
但是,如果您对浪费的资源使用有了深刻的了解并感到满意,那么您会发现清晰的算法可以减少工作量,并且对整体性能/成本有更好的影响。
向开发商致敬
对于那些已经编写了上述代码并怀着最大意愿的人,尤其是该特定代码的原始作者,不要将其视为对有效代码的批评。 取而代之的是,有机会了解无害技术的成本以及更多节俭替代品的可用性。
那些计算机没有变大!
节约用电小贴士