在离子应用程序中加速Levenshtein距离计算

时间:2015-12-16 19:01:15

标签: javascript performance ionic-framework nlp levenshtein-distance

  • 我在做什么:我正在为多种语言开发移动词典应用

  • 我是如何做到的:使用离子框架结合一些角度和一些纯粹的js(从相同语言的在线词典网站导入)

  • 问题:我们的搜索功能是一种近似搜索,它使用Levenstein距离计算器对字典中与查询表单相关的所有条目进行排名。当字典有多达1,500个字时,这在电话上根本不存在问题,但是当字典有大约10,000个字时,在显示结果之前有大约5-8秒的延迟,尽管它在瞬间显示网页浏览器使用"离子服务"。当我运行firebug时,需要花费最长时间来处理的javascript是距离计算,所以我的工作假设是我应该开始的地方,但我可以接受任何建议。

    < / LI>

这是距离计算器:

/**
 * editDistance.js
 * 
 * A simple Levenshtein distance calculator, except weighted such
 * that insertions at the beginning and deletions at the end cost less.
 *
 * AUTHOR: Pat Littell
 * LAST UPDATED: 2015-05-16
 */

var distanceCalculator = {

insertionCost : 1.0,
deletionCost : 1.0,
insertionAtBeginningCost : 0.11,
deletionAtEndCost : 0.1,
substitutionCost : 1.0,

getEditDistance : function(a, b) {
  if(a.length === 0) return b.length; 
  if(b.length === 0) return a.length; 

  var matrix = [];
 // var currentInsertionCost, currentDeletionCost, currentSubstitutionCost = 0;

  // increment along the first column of each row
  var i;
  for(i = 0; i <= b.length; i++){
    matrix[i] = [i * this.insertionAtBeginningCost];
  }

  // increment each column in the first row
  var j;
  for(j = 0; j <= a.length; j++){
    matrix[0][j] = j;
  }

  // Fill in the rest of the matrix
  for(i = 1; i <= b.length; i++){
    for(j = 1; j <= a.length; j++){
        currentInsertionCost = matrix[i][j-1] + this.insertionCost;
        currentSubstitutionCost = matrix[i-1][j-1] + (b.charAt(i-1) != a.charAt(j-1) ? this.substitutionCost : 0);
        currentDeletionCost = matrix[i-1][j] + (j==a.length ? this.deletionAtEndCost : this.deletionCost);            
        matrix[i][j] = Math.min(currentSubstitutionCost, Math.min(currentInsertionCost, currentDeletionCost));

    }
  }

  return matrix[b.length][a.length];
},


// Given a query <a> and a series of targets <bs>, return the least distance to any target
getLeastEditDistance : function(a, bs) {
    var that = this;
    return Math.min.apply(null, bs.map(function(b) {
        return that.getEditDistance(a,b);
    }));
}
}

2 个答案:

答案 0 :(得分:1)

首先,如果您有一个已知字典,您将获得最快的解决方案,例如Levenshtein Automata,这将在线性时间内解决此问题,以获得所有候选人。你无法通过一般目的实现这一点。

据说,这种levenshtein距离的实现比你的快几倍。

map

我也不会在getLeastEditDistance中使用Math.min,这非常慢。只需使用正常循环。另外.propertyname有很多参数也不是很有效。

答案 1 :(得分:0)

我正在与Levenstein距离工作,我没有找到提高性能的好方法,也不建议在非批量应用程序中使用它。

我建议您使用搜索树使用其他方法。二元或三元搜索树也可以找到近匹配。

一个好的起点是那些文章:

http://www.codeproject.com/Articles/5819/Ternary-Search-Tree-Dictionary-in-C-Faster-String

http://www.codeproject.com/Articles/68500/Balanced-Binary-Search-Tree-BST-Search-Delete-InOr

代码相对简单,你不应该花太多时间将它移植到JavaScript。