有一项任务是将数据保存在某些本地存储中或用于网络传输。数据以普通对象形式(键值对)存储。 为了节省带宽和存储空间,我计划使用从冗长的详细密钥名称到相应的数字(使用地图)的转换,并在接收数据时恢复它们。例如:
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压缩算法?
非常感谢。
答案 0 :(得分:2)
您所指的优化可能被称为"令牌替换"或类似的东西,是一种合理的域特定压缩方法。
这种类型的转换并不能防止像gzip这样的基于匹配+熵的算法工作,因此在应用此转换后,您不可能获得更大的最终大小。也就是说,你正在进行的替换完全 gzip擅长的事情类型,所以在调用gzip之前自己做这件事可能有点多余。
要确定,您可以简单地测试!令牌替换+ gzip的典型结果是什么,而不仅仅是gzip?
即使没有测试,以下是基于gzip的令牌替换方法的一些优点和缺点:
基本上,我建议反对它,除非您的测试表明它提供了显着的性能提升。通常它不会,因为gzip已经删除了大部分冗余,但这取决于你的具体情况。
答案 1 :(得分:0)
以下是我对你问题的看法。
如果您使用自己的想法,请不要使用gzip或在数据长于 x 字节时使用它。
最好是不要使用它。
这就是为什么我说不要使用你的方法:
使用您的方法具有以下优点:
但是,你必须考虑这个:
一个例子是,如果将来要添加您不会总是返回的调试信息或字段。这是一个非常基本的例子:
{"error":false,[... data goes here ...]}
{"error":true,"type":"..."}
{"error":500,"desc":"Service unavaliable"}
使用您的代码,第二个字段可以是"desc"
,"type"
或任何其他字段。
您可以说:"我们可以添加desc
和type
字段并始终发送它们!"。现在,您正在添加更多数据,从而无法使用您的方法。
备份我的声明
如果没有一些数据我会得到什么样的答案会备份大胆的陈述,例如"无法压缩"?
让我们考虑您的示例数据:
{"SEARCH":"ui","SORT":"NAME","DISPLAY_FAV":false,"PANEL_POS":0,"MENU_LIST_POS":3,"MAIN_LIST_POS":0,"CHANNEL":""}
你(非最佳)减少到这个:
{"0":"ui","1":"NAME","3":false,"4":0,"5":3,"6":0}
所有压缩值都将使用此基本PHP代码:
$output = '<content>';
echo 'gzip:', strlen(gzencode($output)), ' original:', strlen($output);
其中显示了gzip压缩的大小和原始大小。我将保持代码尽可能简单,以避免疏远非PHP开发人员。
以下是我从不同执行中获得的结果:
{"SEARCH":"ui","SORT":"NAME","DISPLAY_FAV":false,"PANEL_POS":0,"MENU_LIST_POS":3,"MAIN_LIST_POS":0,"CHANNEL":""}
gzip:112 original:112
(+0字节){"0":"ui","1":"NAME","3":false,"4":0,"5":3,"6":0}
gzip:65 original:49
( +16字节超过原始版本)["ui","NAME",false,0,3,0]
(适当的JSON输出,基于您的对象)gzip:45 original:25
( +20字节超过原始版本)您可以尝试http://sandbox.onlinephpfunctions.com/code/d8d0799147e3256ede2b730cb1ded7cf66c1eb67
上的代码输出是从问题中的评论中获得的,而不是由我编写的。除了最后一个,它基于第二个输出。第二个输出显示一个数组表示为一个对象(顺序数字键)。
好的,我说了很多话,显示了一些代码,但没有。我的结论?
对于您的情况,请使用gzip或使用您的方法。我会坚持简单明了的gzip,并称之为一天。
你不会不必要地增加你的输出尺寸。
即便如此,如果你真的想要你的方法,请在你的服务器上禁用gzip并保存CPU cicles。