锟截革拷锟斤拷android培训【03-08】Android学
4.Fast Json高效的原因,为什么推荐使用Fast Json


Fast json高效自然而然是有它的原因的..我主要针对几点来说说..因为我并没有完全的看完Fast Json的源码..只是自己的一些见解,说的也就不是非常的全面..
(1)使用SerializeWriter
将数据封装成Json的时候使用SerializerWriter来完成,通过对字符串的追加将数据转换成Json字串.并且其内部提供了一些优化针对减少数组越界的判断.(减少了越界的判断确实能够提高一部分效率)
ThreadLocal来缓存buf,写入数据必然需要使用缓存来存放字符串的内存地址,但是每次序列化的时候都需要重新分配buf的内存空间,为了避免多次申请内存空间以及gc的调用,因此将内存保存到了ThreadLocal中,当再次进行序列化的时候只需要从ThreadLocal中取出内存就可以了.
并且ThreadLocal不仅仅可以缓存内存地址,当我们对Json数据进行解析的时候也会使用到它提供的缓存..当我们在解析Json的时候,我们读取到的key值可以被保存在一个叫sbuf的缓冲区中,只要这个缓冲区不被释放掉,那么再次读取的时候只需要从缓冲中读取到相关的字符串序列即可,没必要去new一个新的字符串对象,从而导致内存空间的开辟以及不必要的gc调用..
(2)使用asm来避免反射机制的使用
asm不是一个算法,它是字节码框架技术,它可以避免使用Java中的反射机制从而获取到一个类中的所有成员变量和方法,反射机制同样也可以实现,但是反射机制的一大弊病就是耗费时间.使用反射中间会生成大量的临时变量从而导致gc的频繁调用.(避免了反射的使用,自然性能上也有了一定的优化) 至于asm技术我没有进行彻底的研究..可能以后会写..有兴趣的大家可以自己去研究研究..
(3)使用IdentityHashMap去优化性能.
因为Fast Json每种类型都对应一种解析方式,也就出现了<class,JavaBeanSerializer>的映射关系,那么映射自然就需要使用有映射关系的集合,也就是HashMap<K,V>,但是HashMap并不是线程安全的,也就是在并发环境下会导致死循环的出现.因此在并发情况下我们就需要ConcurrentHashMap,但是比HashMap的性能要差,因为需要使用lock()等方法控制多线程的安全问题.安全就失去了效率,因此IndentityHashMap集合就在Fast Json中开发.他的内部去除了transfer方法,使得它能够在并发的情况下也能保证安全性.同样效率也就不会受到影响。
(4)Deserializer的主要优化算法..
Deserializer也成为反序列化过程,也就是将Json数据转化成Java Bean形式.也是优化精力最多的地方.
基于token的预测分析:
解析Json 需要使用到词法处理,Fast Json使用了基于预测的词法分析方式,比如说:比如key之后,最大的可能是冒号":",value之后,可能是有两个,逗号","或者右括号"}" 这样的预测分析。
public void nextToken(int expect) {
/* */ while (true) {
/* 297 */ switch (expect)
/* */ {
/* */ case 12:
/* 299 */ if (this.ch == '{') {
/* 300 */ this.token = 12;
/* 301 */ this.ch = this.buf[(++this.bp)];
/* 302 */ return;
/* */ }
/* 304 */ if (this.ch == '[') {
/* 305 */ this.token = 14;
/* 306 */ this.ch = this.buf[(++this.bp)];
/* 307 */ return;
/* */ }
/* */ case 16:
/* 311 */ if (this.ch == ',') {
/* 312 */ this.token = 16;
/* 313 */ this.ch = this.buf[(++this.bp)];
/* 314 */ return;
/* */ }
/** 中间一堆....*/
if ((this.ch != ' ') && (this.ch != '\n') && (this.ch != '\r') && (this.ch != '\t') && (this.ch != '\f') && (this.ch != '\b')) break;
/* 419 */ this.ch = this.buf[(++this.bp)];
/* */ }
/* */
/* 423 */ nextToken();
/* */ }

预测分析的源代码就是上面粘贴的,只是粘贴了一部分,其实就是对下一个token的预测判断,这样可以帮助我们尽最快的速度拿到token..简单的说一下token的概念..
//这是一个Json字串..其中token单引号引起的部分每一个单引号引起的部分就是一个token这里一共有13个token..{ "id" : 123, "name" : "aa", "salary" : 56789} //json字串 '{' ' "id" ' ':' '123' ',' ' "name" ' ':' ' "aa" ' ',' ' "salary" ' ':' '56789' '}'
这样token的概念就没那么难理解了..
(5)Sort field fast match算法
Fast Json在封装和解析的时候都是默认使用这个算法的,就是以有序的方式将Json 字符串进行保存,如果数据保存的形式是有序的,那么就使用优化算法,不用对每一个token进行处理..只需要处理一部分的token就可以了..也正是因为这个原因,使得Fast Json在解析Json的时候可以减少50%的token...这样效率上就有了空前的变化...如果不是有序的我们就需要一个一个进行分析了,然后从中取出key对应的value值.
就那上面那条Json数据来说吧,如果key值是有序的,那么只需要处理6个token就可以了,但是如果是无序的,就需要处理13个token..处理13个token不难理解..就是对扫描整个字符串,然后处理每一个token不就完事了..但是如果是有序的,那么为什么只需要处理6个token呢?我看了很多人的博客都没有对这块进行讲解..也就使得我也非常的迷茫..
我自己的理解是这样的:其实对不对我自己也不是非常的确定..(如果不对,大家请指出)
之所以只需要处理6个token就是只需要对key和value值进行处理,三对key,value对应的也是6个token,因为我们使用了预测分析,那么自然而然就知道了Json的数据格式,有了这个数据格式,那么那些符号类的token就可以直接跨越过去,我们已经匹配到了key那么自然就预测到key后面有一个","那么这个","我们就不需要处理了,只需要处理","后面的value了..因此符号类的token是没必要处理的,但是为什么要有序,因为我们是将每一条的Json数据转化成字符数组的形式,在匹配key值的时候我们是按照字符数组进行匹配,如果每一条的顺序都不一样,那么就不能使用一条规则去使者多条数据遵循这一个原则进行解析..因此才进行排序,可以减少对token的读取和处理..(个人理解..不对的话,请指出..)
这也就是Fast Json迅速的原因..自然有很多地方的东西没说到..Fast Json说是最快..是不是最快我们说了不算,但是Fast Json确实融入了很多的思想..还是很不错的一个解析Json的api接口..
至于用不用取决于大家..也没必要去争执谁解析Json最快..没什么意义..
原本其实想深入的研究一下,总结一下所有的原因和思想..但是看到很多人写的东西都是九牛一毛..抄来抄去的..没写出核心的东西..等自己真正有时间的时候再去解读一下源码再深入的写吧..
PS:最后只是吐槽一下..如果有人看着不爽..请不要喷我..谢谢!


最后说一下自己学这块的感悟:说实话之所以在Sort Field Fast match算法不是很明白的原因就是没有看到关于这块写的非常优秀的文章,看了挺多人的文章,看着是很厉害,但是写出来的东西大部分都是不清不楚,不明不白,我可以理解使用大量的专业术语(其实就是不说人话)..有的呢就是直接把人家写的东西直接粘贴过去,估计自己都没理解到底是怎么一回事..搬别人的东西不是不可以,只是在搬的时候我们也去想一想,最后结合我们自己的思想写到博客上,那才叫自己真正的学了,博文里才有自己的思想..直接抄来抄去,连改都不改动一下...真的很没意思..


感觉真的挺无力的,Sort这块纠结了很长时间到底要不要写出来,就怕误人子弟...很多博文写的东西只是写一个开头,就拿这个算法为什么只处理了6个token,没有什么过多的解释,什么是asm也没有什么过多的解释..(一开始还以为asm是算法,结果查了一下asm算法和图像处理有关,很明显就弄错了,后来才明白asm是字节码框架技术)..虽然我自己很菜..但是我能保证每一篇文章都是用很大的心思去写,自己心安就行...

贴吧:android培训作者:傻傻的笨老鼠01 2016-03-08 16:16
锟截革拷锟斤拷请教各位PHP大侠一个问题,一定要赐教哦。。
switch(true) 问题就解决了
贴吧:php作者:min134218 2016-03-08 17:23
锟截革拷锟斤拷请教各位PHP大侠一个问题,一定要赐教哦。。
拜托各位,能问这个问题的我非常菜
大家能直接告诉我,缺什么句子,添加在哪,或者把什么句子改成什么吗
拜托大家具体点。。这是书里面的例子。老师说这个程序PHP里面就是这样的,叫我自己上网查,明天检查了,不想认怂啊
$s=0;
switch($s)
{
case $s=100:
echo "满分";
break;
case $s>=90 and $s<100:
echo "优秀";break;
case $s>=60 and $s<90:
echo "及格";
break;
case $s>=0 and $s<60 :
echo "不及格";
break;
default:
echo "无效";
}
贴吧:php作者:拉果格啦嘎 2016-03-08 17:32
锟截革拷锟斤拷利用C#的SWITCH语句设计十二星座速配系统
开着门课刚学没2周 你只要把代码打下就好 多谢
贴吧:c#作者:消逝丶的光芒 2016-03-08 18:13
求助,链表的建立,删除,排序,编译没问题,但运行主程序到调用
#include <stdio.h> #include <stdbool.h> #include <stdlib.h> #include <malloc.h> #include <string.h> #define N
贴吧:c锟斤拷锟斤拷作者:快乐生活zhl 2018-03-24 17:06

大家都在搜

  • switch买哪个版本更好
  • nintendoswitch 官网
  • switch和ps5的区别
  • switch2发售日期已确定
  • switch和ps5怎么选择
  • 任天堂switch游戏大全名单
  • switch下载速度慢怎么办 怎么改
  • switch双人游戏
  • switch字母圈代表什么
  • switch必买的小黄油
  • switch所有游戏列表图
  • switch建议买什么版的
  • switch必玩50款游戏清单
  • nintendo switch online官网
  • switch破解有什么优缺点
  • 任天堂最建议买的三个游戏
  • switch三个版本哪个好
  • switch国行港版日版区别
  • switch耐玩度最高的游戏
  • switchlite
  • switch最值得入手最耐玩
  • switch版本区别
  • Switch有必要破解吗
  • 小白买switch注意什么