在报道谷歌最新版本的语音搜索应用——现在也能用于iOS设备——的过程中,我查阅许多比较苹果(Apple)Siri语音助手和谷歌(Google)语音识别产品间不同之处的文章。显然,这些架构性的决策在很大程度上导致了两款应用的速度差异。
简言之,谷歌语音搜索——谷歌搜索应用的一个功能——在客户端对每一个询问进行语音识别,而苹果Siri则是在服务器端处理这些请求。这意味着,当你按下谷歌应用上的麦克风按钮并开始讲话,理解你的话所需的软件处理过程发生在设备自身。而当你问Siri时,你的设备将问话信息传给远端服务器,由它进行处理然后再把答案一部分一部分地发回到你的设备上。当你对问题进行补充时,Siri会等上好一阵,直到它认为你已经说完了才开始调整输出的答案。苹果这一方法的优势在于,它能使服务器端不断学习,这样用得越多,系统整体就会变得越智能。劣势在于,根据问题的长短以及发音的清晰程度不同,在得到答案之前可能会有许多信息交互(http请求)。在实际使用中,这一区别导致Siri的响应有明显的延时,相比之下谷歌应用几乎是即时识别。
当你深究是什么造就了伟大的应用体验时,你就会遇到这类内容。对于一个应用程序而言,设计和用户界面是你见到的部分,而基础架构及其对性能的影响是你感受到的部分。在进一步讨论之前,我想先稍微岔开话题,说一说真正的建筑界。
我有位朋友在哈佛大学研究伟大的西班牙建筑师拉菲尔·莫尼奥(Rafael Moneo)。上世纪80年代末,这位普利策建筑奖获得者做过一次演讲,当时他用浓重的西班牙口音称自己其中一座建筑是“关于疾病(sickness)和深度”。他的学生们为破解这个高深的表述抓耳挠腮、苦思冥想了好几个钟头,直到他们明白过来他实际上说的是“厚度(thickness)和深度!”
我和我的朋友当时在波士顿吃着台湾菜,当他告诉我这件轶事时,我有点恍然大悟。那时我正在参加Brightcove网站上一个颇为极客的Node.js“框架大比武”(“Framework Smackdown”)的讨论。这些讨论全都围绕着客户端的“厚度”,这已变得比HTML 5网络应用与原生应用之间的区别更为重要。如果想要更详尽了解这个话题,可以看看近期埃里克·辛克(Eric Sink)对这个争论不休的话题的看法。辛克以及皮尔斯着重讨论了客户端设备的性能演进,这可以让开发人员更加明确架构决策,而不仅仅是说“这得视情况而定”。过去5到7年间,网络和应用开发的大部分进步都是凭借“加厚”客户端以及让服务器和客户端的数据能异步交互所取得的。AJAX(Asynchronous JavaScript and XML)是首个对此技术的表述,也最为出名,而Node.js或许是此发展趋势最近也最知名的一个范例。
与莫尼奥的上述表述相对应,对我来说,在应用的架构设计中——服务器和客户端的任务分配以及数据交互协调之间的关系,需考虑的两个重要参数是客户端的最佳“厚度”及相关的底层数据的“深度”。就我现在对比的这两个应用而言,它们的数据深度都很惊人。尽管谷歌的数据明显更深更广,但就设计决策而言,两者都不存在瓶颈。一个明显的疑问是,既然搜索是“场外”活动(指的是搜索计算主要服务器上进行,在终端设备之外——译注),谷歌为什么要把该过程的某个部分放到“场内”来呢?
答案可归结于所谓“关注点分离”的编程风格。让语音识别处理成为硬件设备的一个功能,使得应用程序的这方面功能与实际的数据库查询异步进行。Siri要来回多次收发数据,而谷歌在客户端上解析提问的语音表述,然后只向服务器发出一次请求。我会在随后的文章中对这个问题做更详尽的阐述。与桌面计算机相比,移动设备的其中一个显著特性就是用户与设备间的数据交互量(无论是语音还是触摸)。谷歌语音搜索为此采取的优化方式使其成为了更快捷的选择。