Java:缓存计算结果?

Java:缓存计算结果?,java,caching,comparison,matrix,Java,Caching,Comparison,Matrix,我正在写一个程序来计算一个值,这个值是两个物体之间相似性的度量。比较是可交换的,所以比较(a,b)=比较(b,a) 程序向控制台的输出是所有结果的矩阵。但是,由于矩阵的每次比较都有两次((a,b)和(b,a)),因此我只想通过计算一次来节省时间。缓存这些结果的最佳方式是什么 输出外观的粗略示例: a b c a 0 20 9001 b 20 0 333 c 9001 333 0 听起来你已经在矩

我正在写一个程序来计算一个值,这个值是两个物体之间相似性的度量。比较是可交换的,
所以比较(a,b)=比较(b,a)

程序向控制台的输出是所有结果的矩阵。但是,由于矩阵的每次比较都有两次(
(a,b)
(b,a)
),因此我只想通过计算一次来节省时间。缓存这些结果的最佳方式是什么

输出外观的粗略示例:

    a      b        c
a   0      20      9001

b  20      0      333

c  9001    333      0
听起来你已经在矩阵中缓存结果了。只需计算矩阵中的一个“三角形”,并从中填充其余的:

// Compute one triangle
for (int i=0; i < size; i++)
{
    for (int j=0; j <= i; j++)
    {
        matrix[i][j] = computeValue(i, j);
    }
}

// Now mirror it
for (int i = 0; i < size; i++)
{
    for (int j = i + 1; j < size; j++)
    {
        matrix[i][j] = matrix[j][i];
    }
}
//计算一个三角形
对于(int i=0;i
// Compute one triangle
for (int i=0; i < size; i++)
{
    for (int j=0; j <= i; j++)
    {
        matrix[i][j] = computeValue(i, j);
    }
}

// Now mirror it
for (int i = 0; i < size; i++)
{
    for (int j = i + 1; j < size; j++)
    {
        matrix[i][j] = matrix[j][i];
    }
}
//计算一个三角形
对于(int i=0;i对于(int j=0;j只计算一个三角形,并创建如下访问函数

get(int x, int y) {
  if (x > y) { return matrix[x][y] };
  return matrix[y][x];

只计算一个三角形,并创建如下访问函数

get(int x, int y) {
  if (x > y) { return matrix[x][y] };
  return matrix[y][x];

正如其他人所提到的,您应该只计算三角形的一侧。您也不需要复制它,甚至不需要为它分配空间。只需将x和y坐标转换为单个索引,就可以得到一个略大于全方阵一半大小的数组。例如:

class SymmetricMatrix {
  private final double[];

  /**
   * @param size the size of one dimension of the matrix. eg: 3 for a 3x3 matrix.
   */
  SymmetricMatrix(int size) {
    matrix = new double[index(size) + 1];
  }

  private index(int x, int y) {
    if (x > y) {
      int tmp = x;
      x = y;
      y = tmp;
    }
    // now x <= y
    i = (y * y + y) / 2 + x;
  }

  public double get(int x, int y) {
    return matrix[index(x, y)];
  }

  public void set(int x, int y, double value) {
    matrix[index(x, y)] = value;
  }
}
类对称矩阵{
私人决赛双人[];
/**
*@param size矩阵一维的大小。例如:3x3矩阵为3。
*/
对称矩阵(整数大小){
矩阵=新的双[索引(大小)+1];
}
专用索引(整数x,整数y){
如果(x>y){
int tmp=x;
x=y;
y=tmp;
}

//现在x正如其他人所提到的,你应该只计算三角形的一侧。你也不需要复制它,甚至不需要为它分配空间。只要将你的x和y坐标转换成一个索引,你就可以得到一个略大于全方阵一半大小的数组。例如:

class SymmetricMatrix {
  private final double[];

  /**
   * @param size the size of one dimension of the matrix. eg: 3 for a 3x3 matrix.
   */
  SymmetricMatrix(int size) {
    matrix = new double[index(size) + 1];
  }

  private index(int x, int y) {
    if (x > y) {
      int tmp = x;
      x = y;
      y = tmp;
    }
    // now x <= y
    i = (y * y + y) / 2 + x;
  }

  public double get(int x, int y) {
    return matrix[index(x, y)];
  }

  public void set(int x, int y, double value) {
    matrix[index(x, y)] = value;
  }
}
类对称矩阵{
私人决赛双人[];
/**
*@param size矩阵一维的大小。例如:3x3矩阵为3。
*/
对称矩阵(整数大小){
矩阵=新的双[索引(大小)+1];
}
专用索引(整数x,整数y){
如果(x>y){
int tmp=x;
x=y;
y=tmp;
}

//现在x看起来您不需要它来执行此任务,但是如果您有一个昂贵的函数,并且需要缓存结果,那么这里有一个非常好的线程安全方法:


看起来您不需要它来执行此任务,但如果您有一个昂贵的函数,需要缓存结果,这里有一个非常好的线程安全方法:


对于
compareTo
equals
等方法的缓存结果,您需要相当小心

如果有N个数组实例,则可能需要缓存N^2个比较结果。(这当然取决于应用程序…)

此外,如果应用程序创建和丢弃大量(矩阵)实例,那么缓存中可能会有大量条目,从而导致垃圾保留问题。您可以通过弱引用来缓解这一问题,但它们会显著降低垃圾收集的速度


如果我这样做的话,我会先对应用程序进行分析,以确定<代码> > <代码> >代码>等于方法是真正的瓶颈。如果是,我会考虑使用除缓存之外的其他方法来加速这些方法;例如,用每个数组存储一个懒散计算的散列可以加快<代码>等于< /代码>。需要对

compareTo
equals
等方法的缓存结果相当谨慎

如果有N个数组实例,则可能需要缓存N^2个比较结果。(这当然取决于应用程序…)

此外,如果应用程序创建和丢弃大量(矩阵)实例,那么缓存中可能会有大量条目,从而导致垃圾保留问题。您可以通过弱引用来缓解这一问题,但它们会显著降低垃圾收集的速度


如果我这样做的话,我会先对应用程序进行分析,以确定<代码> > <代码> >代码>等于方法是真正的瓶颈。如果是,我会考虑使用除缓存之外的其他方法来加速这些方法;例如,用每个数组存储一个懒散计算的散列可以加快<代码>等于< /代码>。r矩阵[i][j]=矩阵[j][i]=计算值(i,j);或者,矩阵[i][j]=矩阵[j][i]=计算值(i,j);