幸存者:API -位掩码被投票淘汰

发表在2014年5月12日

今年1月,我加入了Smartsheet,成为API的新开发人员,取代了Kyan,他已经去帮助领导新的平台团队。最初的几个月学习了Smartsheet代码库的里里外外,并致力于我的第一组API增强(参见发布说明),这是一个有趣的过程在这里).

的部落

开发API的有趣之处在于,它基本上处于三个不同团队的交叉点:平台团队,拥有API的路线图和产品管理职责,并代表我们的开发人员社区;ob欧宝娱乐app手机下载移动客户端团队(Android和iOS), API的主要内部“客户”;以及核心开发团队,API是在他们的服务器端代码上构建的。因此,我经常发现自己处于那些团队成员之间充满激情(但又友好:)的辩论中,他们的观点往往很强烈,但关注的问题和观点却相互矛盾。

我在Smartsheet工作才一周,就发现自己第一次陷入了这样的辩论。主题是向通过API检索的列、行和单元格添加格式化信息。格式,比如“这个单元格的文本是红色,黄色高亮,粗体,斜体,24点Verdana”(你知道,当某些内容非常重要的时候!)自然和明显的设计将是添加一个新的JSON对象到列,行和单元格对象,这将有一系列的属性表示不同的格式风格和它们的值,例如{"fontWeight": "bold", "fontSize": 24, "fontFamily": "Arial"(…等等……)}。

但这对手机开发者来说是不可能的。与我们这些拥有高速互联网连接和大量可用内存的服务器端开发者不同,Android和iOS开发者确实需要计算他们的字节数——包括通过有线(或空气,我应该说,想想慢速的蜂窝网络)和内存(最新的iPhone有惊人的1GB RAM)。因此,一想到要加载2万个格式很重的单元格,每个单元格都附加一个沉重的JSON对象,他们就非常紧张。

挑战:将格式添加到API中

会议召开了,来自平台、移动和核心的开发人员提出了解决方案。这是我工作的第二周,我把大部分时间都花在倾听和努力跟上进度上。在会议结束时,我的任务是创建正在考虑的解决方案的原型,并针对它们运行基准测试。

提出了若干解决办法,其中最主要的是:

  1. JSON对象(如上所述):冗长且重量级,但易于构造和使用,因为如果您正在使用API,您就知道如何使用JSON!
  2. 位掩码:类似于我们在后端内部存储格式数据的方式。基本上看起来像一个很长的数值,如“3475892745870102”。数字中的每一组位将对应于一种格式样式(例如,第一个位可能是0表示正常,1表示粗体,第5到12位可能表示不同的前景色颜色等)。紧凑,但解析和组装起来有些痛苦,因为它需要按位运算来读取和构造值。
  3. 数字索引列表:预定义查找表的数字索引列表,并进行了一些优化以进一步减小大小(例如,如果索引值与默认值不变,则省略该索引值)。本文前面的格式示例看起来像这样:“3,8,1,1,,,,,27,21,,,,,,”,其中第一个索引表示预定义字体家族查找表中的值,第二个是字体大小查找表的值,第三个是粗体,第四个是斜体,等等。也紧凑;不像普通的JSON对象那样方便,但比位掩码更方便。

因此,要回答的问题归结为所提议的解决方案之间节省的带宽。如果不考虑大小,我们会选择#1,因为它易于使用,并且与其他API保持一致。类似地,#2似乎是最难使用的,但如果它的尺寸节省比其他两个足够显著,我们就会使用它。我们的手机开发人员可以处理这个问题,我们希望通过即将发布的sdk向外部开发人员隐藏这些丑陋的东西。#3似乎是一个很好的媒介:紧凑,但仍有一定的人类可读性。

(题外话,您可能想知道为什么简单地使用gzip压缩不能解决我们的问题。答案是我们已经在使用gzip了,但是移动客户端仍然必须在内存中保存所有那些庞大的JSON对象和/或解析所有的JSON对象,这两种方法都不便宜。此外,正如你将在下面看到的,基准测试仍然显示,相对于gzip格式的JSON,紧凑格式节省了大量时间。)

选手们决一雌雄

我编写了这些选项的快速且粗糙的版本,并开始使用一些包含不同数量数据和格式的测试表收集基准测试数据。下面是使用重度格式化的大表单(25列,2000行,每个单元格都格式化,100种不同的独特样式)得到的结果:

格式的数据 原始尺寸(MB) gzippped Size (MB)
没有格式包括 8.5 1.7
JSON 24.5 2.7
位掩码 10.2 2.1
指数列表 10.7 2.1

正如预期的那样,JSON方法将有效负载的大小膨胀了很多,几乎是未格式化表的JSON的原始大小的三倍。但要注意的最有趣的事情是位掩码和索引列表选项导致的有效负载大小非常相似。对于开发者来说,这似乎是违反直觉的;一个数字与一组数字的大小大致相同?但是当你记住我们不是通过线路传输原始数据结构时,这是完全有意义的,我们是在传输字符串表示形式这些数据结构(即JSON)。作为一个字符串,数字“123456”与用逗号分隔的小数字“12,3,4”的大小相同。

在我看来,这是关键。我承认这一点可能会损害我的开发者信誉,但我讨厌按位计算。我不喜欢在没有二进制计算器的帮助下无法阅读的数字。左右移动比特和应用异或伤害了我可怜的以10为基础的头脑。我想我并不孤单。我认为在所有条件都相同的情况下,如果要在作为查找表索引的整数列表和带有描述位1到4和5到14代表什么的文档的位掩码之间进行选择,大多数开发人员(非受虐者)会选择前者。

我在其他几张大小和格式不同的表上运行数字,得到了相似的结果:位掩码是最紧凑的,其次是索引列表。我向小组报告了结果。

部落会议:一名幸存者的名字

我们花了很长时间写电子邮件,并就实现的其他细节进行了进一步的讨论,但最终我们确定了索引列表选项。它提供了大小和易用性之间的最佳折衷。为了方便开发人员,我们决定通过一个新的API操作(GET /serverinfo)提供所有的格式查找表,(a)为开发人员省去从文档中手工编写这些表的麻烦,(b)确保开发人员总是拥有最新的表(并不是说我们打算经常更改它们)。

在所有这些之后,我终于开始写该死的代码了!事实证明,这一过程比设计阶段更加顺利,我的劳动成果随着最近Smartsheet的发布而问世。关于格式和新的服务器信息资源的更多信息,请参见API文档.我希望它对你有用!

——凯文

评论

评论