首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将计算值存储在数组中

将计算值存储在数组中
EN

Code Review用户
提问于 2019-01-19 11:05:54
回答 2查看 113关注 0票数 3

在一些地方,我需要计算下一个值,给定一个N:

代码语言:javascript
运行
复制
double size = 1.0 / Math.Pow(2, N);

由于我不会计算N> 15的这个值,所以我想到了以下性能优化:

代码语言:javascript
运行
复制
    public static readonly double[] RegionSizes =
{
    1, 0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125,
    0.00390625, 0.001953125, 0.000976563, 0.000488281, 0.000244141, 0.00012207, 0.00006103515625, 0.000030517578125
};


//Usage
    double size = RegionSizes[N];

这是个好办法吗?为什么/为什么不?

EN

回答 2

Code Review用户

发布于 2019-01-19 21:07:28

这不是一个好的解决方案,有几个原因。

1.:您的值不如双数据类型所允许的精确。例如,

代码语言:javascript
运行
复制
1.0 / Math.Pow(2, 12)

计算为0.000244140625,而查找值仅为0.000244141。根据下面的计算,这可能会产生很大的不同。

2.您的数组是公共的和可变的。虽然数组引用是只读的(因此不能将新数组分配给引用),但数组本身却不是。例如

代码语言:javascript
运行
复制
RegionSizes[2] = 5;

编译和运行,没有任何问题。您(或其他每一个开发人员)可以根据他的意愿覆盖数组中的值。最好使用不可变集合(如ReadOnlyCollection<double> )来防止运行时对缓存值的操作。(如果这是一个有趣的项目,而您是唯一的开发人员,这可能不会成为一个问题;在大于1dev的大型项目中,这种类型的疏忽可能会导致难以跟踪的bug。)

3.经验告诉我们,这样的假设

我不会计算N> 15的这个值

不要总是坚持真理。可以肯定的是,一种更灵活的方法(比如在第一次需要时计算每个值,然后存储它并在需要时再次使用它)将允许更大的灵活性。当然,如果没有任何关于您打算在程序中做什么的信息,就很难判断这是否相关。

4.我强烈怀疑您正在进行过早的优化(因为您没有提到实际的性能问题,也没有提到任何表明浮点操作是造成此类问题的原因的度量)。唐纳德·克努斯

真正的问题是,程序员在错误的地方和错误的时间里花费了太多的时间来担心效率;过早的优化是编程中所有问题(或至少大部分)的根源。

我没什么可补充的。根据我的经验,在>95%的软件项目中,您不需要担心>95%的代码的性能。因此,在进行优化时,您应该遵循以下步骤:

  1. 设定一个现实的、可衡量的绩效目标。这一点很重要,你可以永远优化代码,所以你必须有一些‘足够好’的定义,并停止一旦你的代码足够好。
  2. 衡量是否存在实际的性能问题(通过将实际性能与“足够好”的定义进行比较)。
  3. 确定导致性能问题的代码部分;这涉及再次度量。例如,度量程序在每个方法中花费的时间,然后度量在慢速方法中操作所花费的时间。这样做,直到您确切地知道是什么使您的程序运行缓慢。
  4. 优化步骤3中发现的慢代码,并再次度量,以确保优化使代码运行得更快(有多少“优化”实际上会使情况变得更糟)。
  5. 回到2。

是的,我知道,优化代码很有趣--但是你很快就会迷失方向,花上几百个小时来优化那些根本不需要优化的代码。

票数 5
EN

Code Review用户

发布于 2019-01-19 16:17:14

它可以称为预先计算的本地缓存不可变字段数组。

它很好,而且肯定比每次计算值都要好。

虽然我说不可变,但我并不是说它是深不可变的-所有的值都可以改变,只有数组引用本身是不可变的。如果您需要将它传递给您不完全信任的方法,那么您可以传递一个副本--如果它们混淆了值,那么它就是它们的本地副本。

首先,请确保使用正确的初始值。要做到这一点,您可以使用:https://www.wolframalpha.com/input/?i=N%5B1%2F2%5E(0..15),+15%5D计算它们

代码语言:javascript
运行
复制
N[1/2^(0..15), 15]

这将产生价值

代码语言:javascript
运行
复制
{
  1.00000000000000, 
  0.500000000000000, 
  0.250000000000000, 
  0.125000000000000, 
  0.0625000000000000, 
  0.0312500000000000, 
  0.0156250000000000, 
  0.00781250000000000, 
  0.00390625000000000, 
  0.00195312500000000, 
  0.000976562500000000, 
  0.000488281250000000, 
  0.000244140625000000, 
  0.000122070312500000, 
  0.0000610351562500000, 
  0.0000305175781250000
}

类型double是近似值,最多可信任15个位置,也称为有效数字。计数不是从十进制开始,而是从最高值开始。对于浮点数类型,只有7,小数点是28。这就是为什么我只显示了15位数字。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/211805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档