当前位置: 首页 > 知识库问答 >
问题:

可选的'orElse'延迟评估失败会导致性能下降

雷硕
2023-03-14

考虑具有用户偏好系统的应用程序的以下用例:

我们想得到首选项MyFlag的布尔值
在最佳情况下,我们希望从当前用户的设置中获得它
如果失败,我们希望从默认设置中获取MyFlag<如果失败,抛出。

设置在服务器上。此连接很慢,可能会失败。
获取设置和获取首选项也可能失败。
所以让我们使用javas选项:

public static boolean getMyFlag()throws NoSuchElementException
{
        return getUserOrDefaultPreference("MY_FLAG");
}

private Boolean getUserOrDefaultPreference(String preferenceName) throws NoSuchElementException
{
    return Optional.ofNullable(getConnection())              // get slow connection
        .map(connection -> connection.getUserSettings())     // get user settings
        .map(settings -> settings.getPref(preferenceName))   // return preference
        .orElse(slowlyGetDefaultPreference(preferenceName)); // or else return default value
}

private Boolean slowlyGetDefaultPreference(String preferenceName) throws NoSuchElementException
{
    return Optional.ofNullable(getConnection())             // get slow connection
        .map(connection -> connection.getDefaultSettings()) // get default settings
        .map(settings -> settings.getPref(preferenceName))  // return preference
        .orElseThrow(() ->  new NoSuchElementException());  // if any of the above fails throw
}

这里的问题是连接可能非常慢。当<代码>。orElse(slowlyGet…) slowlyGetDefaultPreference()。这是一个性能惩罚,我必须避免。

我尝试通过. orElseGet(()-使用供应商

因此,我唯一的求助是丑陋的反模式,从可读性的角度来看,它破坏了整个可选流程:

private Boolean getUserOrDefaultPreference(String preferenceName) throws NoSuchElementException
{
    Optional<Boolean> opt = Optional.ofNullable(getConnection())
        .map(connection -> connection.getUserSettings())  
        .map(settings -> settings.getPref(preferenceName));

    if(opt.isPresent())
    {
        return opt.get();
    }
    else
    {
        slowlyGetDefaultPreference(preferenceName));
    }
}

抛出异常也是如此,因为我不想支付构建异常的成本。

我是遗漏了什么还是这是唯一的解决办法?


共有2个答案

花阳秋
2023-03-14

当我测试这个时,它只打印“智能”

public class SampleJava {
    public static String stupid() {
      System.out.println("stupid");
      return "stupid";
    }
    public static void main(String[] args) {
      System.out.println(Optional.ofNullable("smart").orElseGet(() -> stupid()));
    }
}
薛博艺
2023-03-14
匿名用户

orElse()和orElseGet(lambdas)之间的区别在于,第一个函数总是被调用,但是当一些obejct在orElseGet(可选)之前时,调用了orElseGet(可选)。ofNullable()为空。

这意味着,如果您不希望每次都从orElse()调用time方法,则必须使用orElseGet()

在您的示例中,对于您的方法,请使用

return Optional.ofNullable(getConnection())              // get slow connection
    .map(connection -> connection.getUserSettings())     // get user settings
    .map(settings -> settings.getPref(preferenceName))   // return preference
    .orElseGet(() -> slowlyGetDefaultPreference(preferenceName));

然后,当map函数中的所有对象都不为null时,您可以编写不计算最后一个方法的代码

 类似资料:
  • 问题内容: 以下内容在Python 3.6中从不打印任何内容 相反,它只是坐在那里烧坏了CPU。问题似乎在于,如果迭代器位于无限空间内,则永远不会返回迭代器,因为它首先评估完整的迭代器。鉴于假设应该是发电机,这令人惊讶。 我本来希望这会开始计数(到无穷大),就像这个生成器的行为(直接从docs取得): 但是,尽管我的生成器立即开始计数,但使用的生成器根本不计数。 其他工具可以达到我的期望。例如,以

  • 问题内容: 在清理这个答案时,我对MySQL和s和存储过程有了一些了解,但感到震惊的是,尽管and 触发器可以修改数据,但它们似乎不会导致插入/更新失败(即验证)。在这种特殊情况下,我可以通过处理数据以导致主键重复的方式来使其工作,这在这种特殊情况下是有道理的,但在一般意义上不一定有意义。 这种功能在MySQL中可行吗?在其他RDBMS中(可悲的是,我的经验仅限于MySQL)?也许是样式语法? 问

  • 使用方法 性能评估模块提供了一系列用于模型性能评估的函数,这些函数在模型编译时由metrics关键字设置 性能评估函数类似与目标函数, 只不过该性能的评估结果讲不会用于训练. 可以通过字符串来使用域定义的性能评估函数 model.compile(loss='mean_squared_error', optimizer='sgd', metri

  • 使用方法 性能评估模块提供了一系列用于模型性能评估的函数,这些函数在模型编译时由metrics关键字设置 性能评估函数类似与目标函数, 只不过该性能的评估结果讲不会用于训练. 可以通过字符串来使用域定义的性能评估函数,也可以自定义一个Theano/TensorFlow函数并使用之 参数 y_true:真实标签,theano/tensorflow张量 y_pred:预测值, 与y_true形式相同的

  • 描述 我有一个小应用程序,它使用hook更新状态,但每次更新时,都会导致页面延迟。我指的是实际的延迟,而不仅仅是“等待异步”延迟。 我的理论是,更新状态会重新呈现太多的组件,因为如果我将状态减少到更少的值,滞后就会消失。 从本质上说,我担心我更新状态的方式没有隔离我想要的值。 密码 我将回购加载到CodeSandbox:https://codesandbox.io/s/long-forest-y9

  • 问题内容: 我正在类之间进行一些Java性能比较,并想知道是否存在某种Java Performance Framework可以简化编写性能测量代码的过程? 即,我现在正在尝试测量与使用AtomicInteger作为我的“同步器”相比,使用PseudoRandomUsingSynch.nextInt()中的“同步”方法具有什么效果。 因此,我尝试使用3个线程访问10000次同步方法循环来测量生成随机