java开发套路_备份

Optional.orElseGet

Optional<OrderByContext> result = // 省略代码...
return result.orElse(getDefaultOrderByContextWithoutOrderBy(groupByContext));

以上这种使用 orElse 的写法,即使 result 的结果不为空,orElse 里面的方法也会被调用,尤其是 orElse 里面的方法涉及修改操作时,可能会发生意料之外的事情。涉及方法调用的情况下应调整为下面的写法:

Optional<OrderByContext> result = // 省略代码...
return result.orElseGet(() -> getDefaultOrderByContextWithoutOrderBy(groupByContext));

使用 lambda 提供一个 Supplier 给 orElseGet,这样只有 result 为空的时候才会调用 orElseGet 里面的方法。

Java 8 ConcurrentHashMap 的 computeIfAbsent

在JAVA8的Map接口中,增加了一个方法computeIfAbsent,此方法签名如下:

public V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)

如果mappingFunction(key)返回的值为null或抛出异常,则不会有记录存入map
1.ConcurrentHashMap 的 computeIfAbsent 在 key 存在的情况下,仍然会在 synchronized 代码块中获取 value,在对同一个 key 高频调用 computeIfAbsent 的情况下非常影响并发性能。
规避问题的解决

SQLExecutionUnitBuilder result;
if (null == (result = TYPE_TO_BUILDER_MAP.get(type))) {
    result = TYPE_TO_BUILDER_MAP.computeIfAbsent(type, key -> TypedSPIRegistry.getRegisteredService(SQLExecutionUnitBuilder.class, key, new Properties()));
}
return result;

避免高频调用 java.util.Properties

java.util.Properties 是 ShardingSphere 在配置方面比较常用的一个类,Properties 继承了 java.util.Hashtable,因此要避免在并发情况下高频调用 Properties 的方法。
init 方法内完成,避免在分片算法计算逻辑的并发性能。

避免使用Collections.synchronizedMap

String.format性能有影响慎用

fore-each 代替高频 stream

我们发现将压测过程中发现的所有高频 stream 替换为 for-each 后,ShardingSphere-JDBC 的性能提升明显。
以上测试结果也可能和 aarch64 平台及 JDK 有关。不过 stream 本身存在一定开销,性能在不同场景下差异较大,对于高频调用且不确定 stream 能够优化性能的逻辑,我们考虑优先使用 for-each 循环。

hashCode计算

@RequiredArgsConstructor
@Getter
@ToString
public final class Column {

    private final String name;

    private final String tableName;

    @Override
    public boolean equals(final Object obj) {...}

    @Override
    public int hashCode() {
        return Objects.hashCode(name.toUpperCase(), tableName.toUpperCase()); 
    } 
}

显而易见,上面这个类是不可变的,但是却在hashCode 方法的实现中每次都调用方法计算 hashCode。如果这个对象频繁在 Map 或者 Set 中存取,就会多出很多不必要的计算开销。

调整后:

@Getter
@ToString
public final class Column {

    private final String name;

    private final String tableName;

    private final int hashCode;

    public Column(final String name, final String tableName) {
        this.name = name;
        this.tableName = tableName;
        hashCode = Objects.hash(name.toUpperCase(), tableName.toUpperCase());
    }

    @Override
    public boolean equals(final Object obj) {...}

    @Override
    public int hashCode() {
        return hashCode;
    } 
}

使用 lambda 代替反射调用方法

使用反射的方式记录方法调用及重放,反射调用方法本身存在一定的性能开销,且代码可读性欠佳:

@Override
public void begin() {
    recordMethodInvocation(Connection.class, "setAutoCommit", new Class[]{boolean.class}, new Object[]{false});
}

避免反射

@Override
public void begin() {
    connection.getConnectionPostProcessors().add(target -> {
        try {
            target.setAutoCommit(false);
        } catch (final SQLException ex) {
            throw new RuntimeException(ex);
        }
    });
}

UUID.random().toString存在性能差

UUID.randomUUID().toString();修改为
Random random = ThreadLocalRandom.current();
new UUID(random.nextLong(), random.nextLong()).toString();
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值