Javascript 大数数组压缩
我有一个javascript应用程序,它可以发送大量的数字数据。然后,这些数据存储在数据库中。我有大小问题(带宽太大,数据库太大)。我现在准备牺牲一些性能来压缩 我在考虑实现一个base 62 number.toString(62)和parseInt(compressed,62)。这当然会减少数据的大小,但在我继续做这件事之前,我想我会把它告诉这里的人们,因为我知道一定有一些我没有考虑过的开箱即用的解决方案 基本规格为: -将大量数组压缩成字符串以进行JSONP传输(因此我认为UTF已过时) -要相对快一些,看,我不期望像现在这样的性能,但我也不希望gzip压缩 任何想法都将不胜感激 谢谢 Guido Tapia选项Javascript 大数数组压缩,javascript,compression,Javascript,Compression,我有一个javascript应用程序,它可以发送大量的数字数据。然后,这些数据存储在数据库中。我有大小问题(带宽太大,数据库太大)。我现在准备牺牲一些性能来压缩 我在考虑实现一个base 62 number.toString(62)和parseInt(compressed,62)。这当然会减少数据的大小,但在我继续做这件事之前,我想我会把它告诉这里的人们,因为我知道一定有一些我没有考虑过的开箱即用的解决方案 基本规格为: -将大量数组压缩成字符串以进行JSONP传输(因此我认为UTF已过时) -
- 使用js库(参见Josh的答案),但要注意脚本超时
- 使用某种activex或silverlight上传程序,也可以进行压缩
- 使用java插件
- 使用基于flash的压缩上传程序
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)))
函数获取地图{
d={}
对于(var i=0;i我现在正在考虑将数字的长度编码到数字本身中。我仍然没有完善这个算法,但一旦完成就会发布。但大致上这就是我目前试图实现的目标:
边界:
- 允许精度损失(+-3)
- 最大数量为3200
- 最小值为0(因此没有负片)
- 没有十进制浮点数
现在给我的最大允许数,我知道基62中编码数字的最大长度为2。所以任何编码数字的长度都是1或2个字符。太棒了。所以现在我要根据数字的1或2个字符将其设为奇数或偶数(记住我可以处理精度损失)。这样就不需要使用分离器
现在我看到这种方法有70%-80%的压缩率,目前它有很多问题,但我对此感到很兴奋,所以这篇文章鼓励大家围绕这种方法进行讨论。为什么不使用gzip?这有什么问题?(或者更可能的是,缩小)如果你想让它更简单的话,你也可以做一些类似于Huffman或LZW的事情。Huffman用Javascript编码:为了清楚起见-我们是通过Javascript和ajax/jsonp将数据从客户端发送到服务器的?@James:对,我们将一个非常大的数组作为字符串发送到服务器。数组不是JSON格式的(所以没有愚蠢的xml标记-哎呀,我是指大括号)只有一个字符串。在int之间连接('.')。这个字符串还存储在数据库中(这是真正的大小问题)。@Cheeso:我不想在服务器上加载压缩/解压缩。我想要客户端(浏览器)除非你能想出一种在JS中使用复杂压缩算法的方法,否则gzip就不存在了。@nick:我们说的是每个约200k的请求。我们说的是每天约100000个请求,我们保留2周的数据,但是每天100000个请求在增加:)如果我能将这些请求设置为100k,那么我将可以在当前硬件设置的情况下再使用至少6个月。这是我在初始问题(base 62编码)中提出的建议。不过,您的示例确实增加了使用更大基数(128)的可能性然而,我怀疑JSONP传输是否正确,我认为62与它将得到的一样好。感谢代码tho,我将与我的代码进行性能比较。仅供参考,此代码将创建一组全局变量。您可能需要更新它。在get_map:d中将是一个全局变量,在baseconvert中:res、neg和余数都将创建global变量。在那之后我停止了阅读,但这个想法似乎很有趣……如果允许使用二进制,我会使用每个字符中8位中的第一位来询问数字是否继续,但保留31个字符用于“继续”,保留31个字符用于“停止”可能也会起作用。再说一次,你可能已经通过它的声音想到了:-)