zoukankan      html  css  js  c++  java
  • FlatBuffers初探

    我第一次知道FlatBuffers是因为Facebook写的这篇Android的技术博客文章。它主要介绍了FlatBuffers对比JSON的优势,以及Facebook Android App应用了FlatBuffers后,衍生的数据和界面更新的工作流转模式。建议去读一读,作者还是一个中国人哦。

    下面开始介绍了一下FlatBuffers,首先看看它和JSON的对比。

       

    先引用GitHub frogermcs/FlatBuffs上的两张Gif效果图.

    那个Loading菊花是干什么的呢?点击上下两个按钮开始数据解析,而数据解析是故意放在主线程上执行,而Loading菊花能直观的辨别解析过程有没有导致UI卡顿。

    左图,点击"PARSE JSON"按钮是用的Gson解析了一个468KB的Json文件,耗时200-300ms。

    右图,点击"USE FLATBUFFERS",是“解析”同样的Json数据但是用FlatBuffers特有的数据格式文件repos_flat.bin。耗时是<10ms。FlatBuffers“解析”的过程,Loading菊花一直保持着流畅的转动。

    FlatBuffers到底有什么样的魔术,能比JSON快这么多呢?

    其实FlatBuffers实际并没有做数据的解析,repos_flat.bin是按照FlatBuffers数据组织格式生成的Byte数组。

    FlatBuffer的数据解析是靠一层层的offset偏移量的组合计算定位到数据在Byte数组的位置,进而获取目标数据的值 。所以FlatBuffer是需要什么数据,才解析什么数据,并不需要全量解析。

    简单说,FlatBuffers分为vtable区和数据区。vtable区保存的是数据的偏移值,数据区保存的是具体的数据值。

    FlatBuffers的优点和缺点

    优点:

    1. 数据都是从Byte数组中获取,减少解析过程的内存占用,减低了GC发生概率。

        Memory Efficient Serialization Library,FlatBuffers是这么描述自己的。

        这里有别人做的内存检测的数据

    2. 无需全量解析,用到的数据才需要解析。

        想象一个很长的ListView,并不需要在初始状态就把所有的数据都解析出来。滚动到可见状态的item的数据,才需要被解析。

    缺点:

    1. 数据获取都是偏移量计算的解析过程,嵌套层级深的数据,可能带来性能问题。

    2. 不自行做数据缓存的话,每次获取同样的数据会有重复计算。

    3. Byte数据安全性和完整性有顾虑。也有人专门写博客表明不会用FlatBuffer哈哈。

    FlatBuffers的应用

    FlatBuffers还可以“解析”JSON,实际是把JSON数据生成FlatBuffers格式的Byte数组。

    如上图,中间的按钮“PARSE JSON(FLATBUFFERS)”点击执行后解析468KB同样的JSON文件,比Gson节省了约40%的耗时。

    作为应用FlatBuffers的切入点,参考着的frogermsc GitHub Demo,我尝试把FlatBuffer解析JSON应用到工作项目中。

    步骤:

    1. 使用FlatBuffers需要引入2个SO和一个JAR,合计1MB;

    2. 根据待解析的数据,要写一个schema文件如下,类似于protocolBuffer的.proto文件的作用;

    namespace RankDetail;
    
    table RankDetail {
        code : int;
        msg : string;
    }
    
    root_type RankDetail;

    3. 通过命令行,根据schema生成相关解析后数据读取的Java类,这个步骤也类似protocolBuffer;

    遇到的问题:

    1. schema文件的Key-value对的Key不能数字开头,如下的123key是不符合要求的;

        原因是因为,FlatBuffers是直接获取schema文件内的这种key-value的key的值作为方法名字和变量名字,阿拉伯数字开头的变量名和方法名是不合法的。

    namespace RankDetail;
    
    table RankDetail {
        code : int;
        msg : string;
        123key : string;
    }
    
    root_type RankDetail;

    2. 解析是在SO的native代码,遇到失败就会native crash,缺少有用的解析失败的日志信息,增加开发调试的难度和时间。

    FlatBuffers最大的威力是解析他自家格式的Byte数组(参考文章开头的GIF对比),应用到正式环境的功能,需要后台请求返回的数据是FlatBuffers格式的Bytes数组。另外,FlatBuffers解析的容错性目前还有待完善提升。但以后,FlatBuffers会是减少内存占用、提升用户体验的利器。

  • 相关阅读:
    软件构造—— 实验二 lex词法分析
    软件构造-实验1 根据状态转换图手工构造词法扫描器
    PHP——实验四 PHP操作数据库
    判断是不是素数
    hexo和github pages的关系
    Python的map,reduce,filter函数
    CentOS源码更新Linux最新内核
    CentOS打Meltdown等漏洞的补丁包
    let申明与const申明
    正则表达式
  • 原文地址:https://www.cnblogs.com/wingyip/p/5185593.html
Copyright © 2011-2022 走看看