-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
537 additions
and
231 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
"use strict"; | ||
exports.__esModule = true; | ||
/* eslint-disable @typescript-eslint/no-var-requires */ | ||
/* eslint-disable no-console */ | ||
var Benchmark = require("benchmark"); | ||
var mod_js_1 = require("./mod.js"); | ||
var fast_levenshtein_1 = require("fast-levenshtein"); | ||
var fs = require("fs"); | ||
var jslevenshtein = require("js-levenshtein"); | ||
var leven = require("leven"); | ||
var levenshteinEditDistance = require("levenshtein-edit-distance"); | ||
var suite = new Benchmark.Suite(); | ||
var randomstring = function (length) { | ||
var result = ""; | ||
var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; | ||
var charactersLength = characters.length; | ||
for (var i = 0; i < length; i++) { | ||
result += characters.charAt(Math.floor(Math.random() * charactersLength)); | ||
} | ||
return result; | ||
}; | ||
var randomstringArr = function (stringSize, arraySize) { | ||
var i = 0; | ||
var arr = []; | ||
for (i = 0; i < arraySize; i++) { | ||
arr.push(randomstring(stringSize)); | ||
} | ||
return arr; | ||
}; | ||
var arrSize = 1000; | ||
if (!fs.existsSync("data.json")) { | ||
var data_1 = [ | ||
randomstringArr(4, arrSize), | ||
randomstringArr(8, arrSize), | ||
randomstringArr(16, arrSize), | ||
randomstringArr(32, arrSize), | ||
randomstringArr(64, arrSize), | ||
randomstringArr(128, arrSize), | ||
randomstringArr(256, arrSize), | ||
randomstringArr(512, arrSize), | ||
randomstringArr(1024, arrSize), | ||
]; | ||
fs.writeFileSync("data.json", JSON.stringify(data_1)); | ||
} | ||
var data = JSON.parse(fs.readFileSync("data.json", "utf8")); | ||
var _loop_1 = function (i) { | ||
var datapick = data[i]; | ||
if (process.argv[2] !== "no") { | ||
suite | ||
.add("".concat(i, " - js-levenshtein"), function () { | ||
for (var j = 0; j < arrSize - 1; j += 2) { | ||
jslevenshtein(datapick[j], datapick[j + 1]); | ||
} | ||
}) | ||
.add("".concat(i, " - leven"), function () { | ||
for (var j = 0; j < arrSize - 1; j += 2) { | ||
leven(datapick[j], datapick[j + 1]); | ||
} | ||
}) | ||
.add("".concat(i, " - fast-levenshtein"), function () { | ||
for (var j = 0; j < arrSize - 1; j += 2) { | ||
(0, fast_levenshtein_1.get)(datapick[j], datapick[j + 1]); | ||
} | ||
}) | ||
.add("".concat(i, " - levenshtein-edit-distance"), function () { | ||
for (var j = 0; j < arrSize - 1; j += 2) { | ||
levenshteinEditDistance(datapick[j], datapick[j + 1]); | ||
} | ||
}); | ||
} | ||
suite.add("".concat(i, " - fastest-levenshtein"), function () { | ||
for (var j = 0; j < arrSize - 1; j += 2) { | ||
(0, mod_js_1.distance)(datapick[j], datapick[j + 1]); | ||
} | ||
}); | ||
}; | ||
// BENCHMARKS | ||
for (var i = 0; i < 9; i++) { | ||
_loop_1(i); | ||
} | ||
var results = new Map(); | ||
suite | ||
.on("cycle", function (event) { | ||
console.log(String(event.target)); | ||
if (results.has(event.target.name[0])) { | ||
results.get(event.target.name[0]).push(event.target.hz); | ||
} | ||
else { | ||
results.set(event.target.name[0], [event.target.hz]); | ||
} | ||
}) | ||
.on("complete", function () { | ||
console.log(results); | ||
}) | ||
// run async | ||
.run({ async: true }); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
declare const distance: (a: string, b: string) => number; | ||
declare const closest: (str: string, arr: readonly string[]) => string; | ||
export { closest, distance }; | ||
//# sourceMappingURL=mod.d.ts.map |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../mod.ts"],"names":[],"mappings":"AAiHA,QAAA,MAAM,QAAQ,MAAO,MAAM,KAAK,MAAM,KAAG,MAaxC,CAAC;AAEF,QAAA,MAAM,OAAO,QAAS,MAAM,OAAO,SAAS,MAAM,EAAE,KAAG,MAWtD,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
const peq = new Uint32Array(0x10000); | ||
const myers_32 = (a, b) => { | ||
const n = a.length; | ||
const m = b.length; | ||
const lst = 1 << (n - 1); | ||
let pv = -1; | ||
let mv = 0; | ||
let sc = n; | ||
let i = n; | ||
while (i--) { | ||
peq[a.charCodeAt(i)] |= 1 << i; | ||
} | ||
for (i = 0; i < m; i++) { | ||
let eq = peq[b.charCodeAt(i)]; | ||
const xv = eq | mv; | ||
eq |= ((eq & pv) + pv) ^ pv; | ||
mv |= ~(eq | pv); | ||
pv &= eq; | ||
if (mv & lst) { | ||
sc++; | ||
} | ||
if (pv & lst) { | ||
sc--; | ||
} | ||
mv = (mv << 1) | 1; | ||
pv = (pv << 1) | ~(xv | mv); | ||
mv &= xv; | ||
} | ||
i = n; | ||
while (i--) { | ||
peq[a.charCodeAt(i)] = 0; | ||
} | ||
return sc; | ||
}; | ||
const myers_x = (b, a) => { | ||
const n = a.length; | ||
const m = b.length; | ||
const mhc = []; | ||
const phc = []; | ||
const hsize = Math.ceil(n / 32); | ||
const vsize = Math.ceil(m / 32); | ||
for (let i = 0; i < hsize; i++) { | ||
phc[i] = -1; | ||
mhc[i] = 0; | ||
} | ||
let j = 0; | ||
for (; j < vsize - 1; j++) { | ||
let mv = 0; | ||
let pv = -1; | ||
const start = j * 32; | ||
const vlen = Math.min(32, m) + start; | ||
for (let k = start; k < vlen; k++) { | ||
peq[b.charCodeAt(k)] |= 1 << k; | ||
} | ||
for (let i = 0; i < n; i++) { | ||
const eq = peq[a.charCodeAt(i)]; | ||
const pb = (phc[(i / 32) | 0] >>> i) & 1; | ||
const mb = (mhc[(i / 32) | 0] >>> i) & 1; | ||
const xv = eq | mv; | ||
const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb; | ||
let ph = mv | ~(xh | pv); | ||
let mh = pv & xh; | ||
if ((ph >>> 31) ^ pb) { | ||
phc[(i / 32) | 0] ^= 1 << i; | ||
} | ||
if ((mh >>> 31) ^ mb) { | ||
mhc[(i / 32) | 0] ^= 1 << i; | ||
} | ||
ph = (ph << 1) | pb; | ||
mh = (mh << 1) | mb; | ||
pv = mh | ~(xv | ph); | ||
mv = ph & xv; | ||
} | ||
for (let k = start; k < vlen; k++) { | ||
peq[b.charCodeAt(k)] = 0; | ||
} | ||
} | ||
let mv = 0; | ||
let pv = -1; | ||
const start = j * 32; | ||
const vlen = Math.min(32, m - start) + start; | ||
for (let k = start; k < vlen; k++) { | ||
peq[b.charCodeAt(k)] |= 1 << k; | ||
} | ||
let score = m; | ||
for (let i = 0; i < n; i++) { | ||
const eq = peq[a.charCodeAt(i)]; | ||
const pb = (phc[(i / 32) | 0] >>> i) & 1; | ||
const mb = (mhc[(i / 32) | 0] >>> i) & 1; | ||
const xv = eq | mv; | ||
const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb; | ||
let ph = mv | ~(xh | pv); | ||
let mh = pv & xh; | ||
score += (ph >>> (m - 1)) & 1; | ||
score -= (mh >>> (m - 1)) & 1; | ||
if ((ph >>> 31) ^ pb) { | ||
phc[(i / 32) | 0] ^= 1 << i; | ||
} | ||
if ((mh >>> 31) ^ mb) { | ||
mhc[(i / 32) | 0] ^= 1 << i; | ||
} | ||
ph = (ph << 1) | pb; | ||
mh = (mh << 1) | mb; | ||
pv = mh | ~(xv | ph); | ||
mv = ph & xv; | ||
} | ||
for (let k = start; k < vlen; k++) { | ||
peq[b.charCodeAt(k)] = 0; | ||
} | ||
return score; | ||
}; | ||
const distance = (a, b) => { | ||
if (a.length < b.length) { | ||
const tmp = b; | ||
b = a; | ||
a = tmp; | ||
} | ||
if (b.length === 0) { | ||
return a.length; | ||
} | ||
if (a.length <= 32) { | ||
return myers_32(a, b); | ||
} | ||
return myers_x(a, b); | ||
}; | ||
const closest = (str, arr) => { | ||
let min_distance = Infinity; | ||
let min_index = 0; | ||
for (let i = 0; i < arr.length; i++) { | ||
const dist = distance(str, arr[i]); | ||
if (dist < min_distance) { | ||
min_distance = dist; | ||
min_index = i; | ||
} | ||
} | ||
return arr[min_index]; | ||
}; | ||
export { closest, distance }; |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.