有一个任务是将数据保存在一些本地存储中或者用于网络传输。数据以普通对象形式(键值对)存储。 为了节省带宽和存储空间,我计划使用从冗长的键名称到相应数字(使用映射)的转换,并在接收数据时恢复它们。例如:
var statesMap = {
SEARCH: 0,
SORT: 1,
FILTER: 2,
DISPLAY_FAV: 3,
PANEL_POS: 4,
MENU_LIST_POS: 5,
MAIN_LIST_POS: 6,
INFO_LIST_POS: 7,
CHANNEL: 8
};
config = {
APP: ['SEARCH', 'SORT', 'DISPLAY_FAV', 'PANEL_POS', 'MENU_LIST_POS', 'MAIN_LIST_POS', 'CHANNEL']
};
app.state = {};
// restore state from {"0":"ui","1":"NAME","3":false,"4":0,"5":3,"6":0}
config[appName.toUpperCase()].forEach(function ( state ) {
var value = storage[statesMap[state]]; // 'storage' stores my data
// convert "compressed" properties to full equivalents
app.state[state] = value != null ? value : '';
});
// result {"SEARCH":"ui","SORT":"NAME","DISPLAY_FAV":false,"PANEL_POS":0,"MENU_LIST_POS":3,"MAIN_LIST_POS":0,"CHANNEL":""}
// store data
var tmp = {};
// filter fields with empty values, don't store them
Object.keys(app.state).filter(function ( key ) { return !!String(app.state[key]); }).forEach(function ( state ) {
tmp[statesMap[state]] = app.state[state];
});
storage = tmp;
这种方法是否有足够的好处和优势?有没有更好的优化?此优化是否会干扰 gzip 压缩算法?
非常感谢。
最佳答案
您所指的优化可能被称为“ token 替换”或类似的东西,并且是一种合理的特定于域的压缩方法。
这种类型的转换不会阻止基于匹配+熵的算法(如 gzip)工作,因此您不太可能在应用此转换后获得更大的最终大小。也就是说,您正在做的替换正是 gzip 擅长做的事情类型,因此在调用 gzip 之前自己做可能有点多余。
要确定,您可以简单地测试一下!与单独使用 gzip 相比, token 替换 + gzip 的典型结果是什么?
即使没有测试,以下也是基于 gzip 之前 token 替换方法的一些优点和缺点:
优势
- 有时您可以比 gzip 更有效地进行 token 替换,如果您在输出生成的早期进行,并且可以在您的大部分处理链中使用这种更紧凑的形式。您可能会在代码的其他部分获得加速,因为诸如字符串比较之类的东西现在已被非常快速的整数比较所取代(但是,请参见缺点 #1)。
- gzip 有一定的局限性,部分原因在于它的使用年限和广泛的目标硬件,您可以通过 token 替换来解决这些局限性。例如,它仅在 32 KiB 窗口中找到匹配项,而您的 token 替换适用于整个格式。
- token 替换有效地利用了您对格式的了解,从而比 gzip 更有效地进行编码。例如,尽管 gzip 将执行与您对频繁出现的键的替换大致相同的替换,但您的替换将对不常出现的键执行良好(但如果它们很多则无关紧要)。实际上,您可以使用有助于压缩的预分发带外字典。
缺点
- Gzip 通常可以使用您的操作系统或运行时环境提供的 native 库高效地实现。特别是因为您无论如何都在调用 gzip,只是使用 gzip 可能比在语言级别进行 token 替换更快。快多少(或慢多少)在很大程度上取决于您的实现。
- 压缩方面的 gzip 主要执行与您相同的替换操作(还有更多),因此您自己替换标记有点多余。也就是说,gzip 查找“匹配项”:文本中较早出现的字符串,并用标记替换它们,就像您所做的那样。此外,它还有很多其他好处,例如对 token 进行熵编码,因此无论如何您都希望将其作为最后一步。
- 添加您自己的预压缩步骤可能不会损害压缩(即使它没有多大帮助),但它会增加复杂性、错误来源、可能的性能问题等等。您需要以某种方式将 key <-> 整数映射传输到远程客户端等。
基本上,我会建议反对它,除非您的测试表明它提供了显着的性能提升。通常不会,因为 gzip 已经删除了大部分冗余,但这取决于您的具体情况。
关于javascript - 压缩效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41116858/