gpt4 book ai didi

java - 与其过程计数器部分相比,优化 Java 8 功能算法

转载 作者:搜寻专家 更新时间:2023-11-01 02:06:34 24 4
gpt4 key购买 nike

我正在尝试优化 Java 8 中的功能操作,而不是它的过程等效操作,但我遇到了一些严重的性能问题。

情况

我必须解析 HTTP header String, List<String>来自将 HeaderName 映射到许多可能变体的给定枚举的值 String, Set<String> .

例子

给定以下 HttpHeaders :

public static final Map<String, List<String>> httpHeaders = new HashMap<>();

httpHeaders.put("Content-Type", Arrays.asList("application/json", "text/x-json"));
httpHeaders.put("SID", Arrays.asList("ABC123"));
httpHeaders.put("CORRELATION-ID", Arrays.asList("ZYX666"));

还有我的自定义枚举:

日志 header

protected final String key;
protected final Set<String> variation;

SESSION_ID("_sid", Arrays.asList("SESSION-ID", "SID"));
CORRELATION_ID("cid", Arrays.asList("CORRELATION-ID", "CID")),


private LogHeaders(final String logKey, final List<String> logKeyVariations) {

this.logKey = logKey;
this.logKeyVariations = new HashSet<>(logKeyVariations);
}

@Override
public String toString() {

return this.logKey;
}

结果应该是“LogHeaders.key”的映射以及来自 HttpHeader 的相应变体的值集。对于给定的 header ,只有一种变体是可能的:

// {LogHeaders.key : HttpHeaderValue>
{
_sid=[ABC123],
_cid=[ZYX666]
}

程序代码

final Map<String, List<String>> logHeadersToValue = new HashMap<>();

for (final LogHeaders header : LogHeaders.values()) {
for (final String variation : header.getLogKeyVariations()) {
final List<String> headerValue = httpHeaders.get(variation);
if (headerValue != null) {
logHeadersToValue.put(header.logKey, headerValue);
break;
}
}
}

功能代码

final Map<String, List<String>> logHeadersToValue =
EnumSet.allOf(LogHeaders.class)
.stream()
.collect(Collectors.toMap(
LogHeaders::toString,
logHeader -> logHeader.getLogKeyVariations().stream()
.map(variation -> httpHeaders.get(variation)).filter(Objects::nonNull)
.collect(singletonCollector())));


public static <T> Collector<T, ?, T> singletonCollector() {

return Collectors.collectingAndThen(Collectors.toList(), list -> {
if (list.size() < 1) {
return null;
}
return list.get(0);
});
}

当前基准

FunctionalParsing : 0.086s

ProceduralParsing : 0.001s

您知道如何优化我的功能部分吗?

谢谢

更新基准

我使用@Tagir Valeev 代码运行了 100k 预热 + 100k 迭代:

FunctionalParsing : 0.040s

ProceduralParsing : 0.010s

更新基准#2

我使用@Misha 代码运行了 100k 预热 + 100k 迭代:

FunctionalParsing : 0.025s

ProceduralParsing : 0.017s

最佳答案

我绝对确定您做的基准测试不正确。您可能只执行了一次。您不关心您的程序运行 0.001 秒还是 0.086 秒,对吧?它仍然比你眨眼还快。所以你可能想多次运行这段代码。但是您似乎只测量了一次时间,并且错误地假设每次连续运行都将花费大致相同的时间。在第一次启动期间,代码主要由解释器执行,而稍后将进行 JIT 编译,运行速度会快得多。这对于与流相关的代码非常重要。

至于您的代码,似乎不需要自定义收集器。你可以这样实现它:

final Map<String, List<String>> logHeadersToValue =
EnumSet.allOf(LogHeaders.class)
.stream()
.collect(Collectors.toMap(
LogHeaders::toString,
logHeader -> logHeader.getLogKeyVariations().stream()
.map(httpHeaders::get).filter(Objects::nonNull)
.findFirst().orElse(null)));

此解决方案也可能更快,因为它不会读取多个 http header (就像它是通过程序代码中的 break 完成的)。

关于java - 与其过程计数器部分相比,优化 Java 8 功能算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31411960/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com