javascript - 大数数组压缩

标签 javascript compression

我有一个 javascript 应用程序,可以通过网络发送大量数字数据。然后将此数据存储在数据库中。我有大小问题(带宽太多,数据库变得太大)。我现在准备牺牲一些性能来进行压缩。

我正在考虑实现一个以 62 为基数的 number.toString(62) 和 parseInt(compressed, 62)。这肯定会减少数据的大小,但在我继续这样做之前,我想我会把它交给这里的人,因为我知道一定有一些我没有考虑过的开箱即用的解决方案。

基本规范是: - 将大量数组压缩成字符串以进行 JSONP 传输(所以我认为 UTF 已经过时了) - 相对较快,看起来我并不期待与现在相同的性能,但我也不想要 gzip 压缩。

任何想法将不胜感激。

谢谢

吉多·塔皮亚

最佳答案

另一种方法可能是编码为二进制类型,例如有符号/无符号整数,并像 http://snippets.dzone.com/posts/show/685 那样手动解码,这需要服务器端代码来创建二进制数据。

然后您可以使用哈夫曼压缩或类似 RLE 的东西(参见 http://rosettacode.org/wiki/Run-length_encoding#JavaScript 的实现,尽管在不修改的情况下它在 IE 中可能有一些问题)进一步压缩数据。

编辑: 或者,您可以将数字本身转换为未编码 URI 字符范围(请参阅 http://en.wikipedia.org/wiki/Percent-encoding )中的基数(基数),如果许多数字大于 2 位数字,这应该会很好地工作。我将 http://code.activestate.com/recipes/111286-numeric-base-converter-that-accepts-arbitrary-digi/ 中的代码从 python 转换为执行此操作。

它目前不处理 float ,但可以很容易地完成:

function get_map(s) {
    d = {}
    for (var i=0; i<s.length; i++) {
        d[s.charAt(i)] = i}
    d.length = s.length
    d._s = s
    return d}

var separate_with = '~';
var encodable = get_map('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.'); // - is reserved for negatives obviously :-P
var base10 = get_map('0123456789')

// UNCOMMENT ME for length/speed testing in a wider base!
// You may wish to experiment with the ranges for a happy medium between bandwidth and DB space :-P
/*var encodable = ''
for (var i=1; i<128; i++) {
    encodable += String.fromCharCode(i)
}
encodable = get_map(encodable)*/

function baseconvert(number, fromdigits, todigits) {
    var number = String(number)

    if (number.charAt(0) == '-') {
        number = number.slice(1, number.length)
        neg=1}
    else {
        neg=0}

    // make an integer out of the number
    var x = 0
    for (var i=0; i<number.length; i++) {
        var digit = number.charAt(i)
        x = x*fromdigits.length + fromdigits[digit]
    }

    // create the result in base 'todigits.length'
    res = ""
    while (x>0) {
        remainder = x % todigits.length
        res = todigits._s.charAt(remainder) + res
        x = parseInt(x/todigits.length)
    }

    if (neg) res = "-"+res
    return res
}

function encodeNums(L) {
    var r = []
    for (var i=0; i<L.length; i++) {
         r.push(baseconvert(L[i], base10, encodable))
    }
    return r.join(separate_with)
}

function decodeNums(s) {
    var r = []
    var s = s.split(separate_with)
    for (var i=0; i<s.length; i++) {
         r.push(parseInt(baseconvert(s[i], encodable, base10)))
    }
    return r
}

var test = [5, 654645, 24324, 652124, 65, 65289543, 65278432, 643175874158, 652754327543]
alert(encodeNums(test))
alert(decodeNums(encodeNums(test)))

关于javascript - 大数数组压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2596494/

相关文章:

javascript - 下拉 Bootstrap 行为很奇怪

javascript - 如何在 Angular 库的 node_modules 文件夹之外使用 *.d.ts?

javascript - PHP 导航链接在 localhost 上有效,但在 live 的服务器 public_html 上无效

javascript - Select2 无法在引导模式下工作

javascript - 在 strongloop 中基于其他表从一个表中提取信息的查询

compression - 我们应该使用什么压缩格式;我们应该放下 DEFLATE (.zip) 休息吗?

c# - 压缩内存流但保留为流(不创建文件)?

c++ - C/C++ 的压缩库能够处理数组中超过 32 位的元素

java - 使用 Maven 进行 XML/XSL 压缩

java - 在 Android 应用程序中读取 10mb 大文本文件