繁体   English   中英

大数阵列压缩

[英]Large number array compression

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

我正在考虑实现一个base 62.toString(62)和parseInt(压缩,62)。 这肯定会减少数据的大小,但在我继续这样做之前,我想我会把它放在这里的人们,因为我知道必须有一些我没有考虑过的解决方案。

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

任何想法将不胜感激。

谢谢

Guido Tapia

另一种方法可能是编码为二进制类型,如有符号/无符号整数,并手动解码,如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位数。 我从python转换了http://code.activestate.com/recipes/111286-numeric-base-converter-that-accepts-arbitrary-digi/上的代码来执行此操作。

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

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)))

选项

  • 使用js库(请参阅Josh的回答),但要注意脚本超时
  • 使用某种也可以拉链的activex或silverlight上传器
  • 使用java插件
  • 使用基于闪存的压缩上传器

我现在正在考虑将数字长度编码为数字本身的想法。 我还没有完善这个算法,但一旦完成就会发布。 但大致这是我目前正在努力实现的目标:

边界:

  • 允许精度损失(+ - 3)
  • 最大数量为3200
  • 最小为0(所以没有否定)
  • 没有小数 - 浮点数

因此,现在给出我的最大允许数量,我知道基数62中的编码数字的长度将具有最大长度2.因此任何编码的数字长度为1或2个字符。 真棒。 所以现在我要将数字设为奇数或者甚至取决于它的1或2个字符(记住我可以处理丢失的准确性)。 这消除了对分离器的需要。

现在我看到了大约70%-80%的压缩,目前它非常多,但是我很兴奋,所以鼓励围绕这种方法的讨论。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM