【译文】NginScript – 为什么我们要实现自己的JS引擎?

在上周的nginx.conf 2015用户大会上,我们发布了全新的JavaScript引擎nginscript的预览版。历史上,JavaScript语言已经应用在许多方面,首先是作为客户端脚本,然后又被用于服务器后台开发。至于nginscript,我们要介绍的是第一种"代理端"的使用情况,用于满足我们在会上提出的一系列独特的要求。消息公布后,许多人对我们决定要实现一个新的JavaScript引擎,而不是使用V8SpiderMonkey,或其他的已有引擎而感到好奇,所以这篇文章用于解释我们为什么这么做。


我们正在做什么?
我们正在编写自己的JavaScript引擎,称为nginscriptnginscript目前支持解析器ECMAScript 5的一个子集(我们将在未来进行扩展),采用基于寄存器的虚拟机(VM),运行时将把代码编译成字节码,同时支持 nginxnginx plus。在目前的预览阶段,nginx可以编译JavaScript代码并用在两个场景:产生nginx的配置,或者在nginx执行阶段生成内容。未来的版本将支持更多的使用场景。


为什么要创建自己的JavaScript运行时?
Nginx
有一些特别的需求导致我们要去创造属于我们自己的引擎。为了扩展请求应的处理流程,我们需要nginx在处理一个请求时可以运行nginscript片段。我们不寻求创造一个后端JavaScript应用程序执行环境因为Node.js已经做的很好。目前的JavaScript引擎被设计为运行在一个Web浏览器中,他们依靠垃圾收集器的管理内存。如果耗尽内存,JavaScript VM会异常退出;这种行为对于浏览器是可以容忍的。但是对于持有数千个连接的服务器却不行,总的来说,专门为浏览器设计的引擎不适合服务器,包括v8SpiderMonkey它们没有供简单的方法来控制执行(即预防奔溃和恢复虚拟机的机制),同时支持JIT的能力有限。我们希望能有一种引擎将nginscript的脚本简单并快速的执行。同时,由此产生的状态被保存在虚拟机外部。因为脚本简单,所以全面支持JavaScript语言没有必要。同时,nginx已经拥有非常精细的事件驱动架构,我们不想nginx的性能受到垃圾收器的影响。

相反,我们正在创建一个非常简单的引擎以满足我们的要求:
架构使用单线程,字节码的执行部分将会非常快速。为每个请求分配虚拟机。因为没有复杂的状态需要初始化,这种简单的虚拟机可以快速启动,同时使用简单的缓存池管理内存。这种内存管理方案,无需跟踪和释放单个对象或使用垃圾回收器,可以大大提高性能。
辅助功能 –Nginx实现了许多内置操作。例如,复杂的数学运算,哈希函数,当nginscriptnginx结合时,这些操作也会是本地的。你可以使用nginscript以编程的方式来驱动nginx的本地方法。
nginx配合 – nginx的事件驱动模型可以用于调度nginscript VMS的执行。当一个nginscript正在执行阻塞操作(如读取网络数据),nginx可以暂停该VM的执行,当该VM的事件完成后再恢复。这意味着你可以在编写一个简单的脚本, nginx会调度脚本不造成阻塞。最后,用我们自己的引擎,我们可以保证API统一,同时确保我们的VMnginx支持的平台范围一致。

 

关于性能
现在谈论性能还过早,目前我们正在专注于功能的实现。nginscript编译为内部的字节码并且运行在一个基于寄存器的虚拟机;这种机制使得它和其他解释性语言(PHPRuby,等等)性能相当。所以为了提高性能,我们想在一些地方增加JIT编译,但这可能会限制支持的平台范围。nginscript只是被设计用来执行一些简单的内部脚本,我们不想让它来执行计算密集型操作,因为nginx内部基于C语言的模块已经解决这个问题。

未来
nginscript
目前处于其发展的早期阶段,我们称当前版本是"预览"版。我们将重点放在核心语言的实现(如增加闭包),并实施许多内置的JavaScript对象(日期,数学,等等)。
我们还将重点放在如何整合资源,比如nginx的配置如何集成脚本,在哪些方面nginscript可以访问和控制nginx内部?如何在脚本之间共享数据,以及跨集群?用户如何调试nginscript脚本?
对于长时间运行的脚本(如WebSocket),我们甚至可以添加一个垃圾收集器,但那是在未来很久以后。
对于nginscript未来如何发展目前还没有定论。我们希望得到您的反馈。请在我们的邮件列表中分享您的想法和见解,我们将共同开发这个功能。谢谢你。

转载于:https://www.cnblogs.com/AlwaysFixBug/p/4857559.html

实现原文和译文对比,找到原文对应译文的句子可以使用Java中的字符串匹配算法,如KMP算法或Boyer-Moore算法。 以KMP算法为例,可以按照以下步骤实现原文和译文的对比: 1. 将原文和译文分别存储到两个字符串中。 2. 使用KMP算法在原文中查找每个句子的开头位置,并记录下来。 3. 对于每个原文的句子开头位置,使用KMP算法在译文中查找对应的句子,并记录下来。 4. 将原文和译文中对应的句子用特定的标记标记出来,如加粗或者下划线。 下面是一个简单的Java代码实现: ```java import java.util.ArrayList; import java.util.List; public class CompareSentences { public static void main(String[] args) { String article = "This is the original text. It contains several sentences. Each sentence ends with a period."; String translation = "这是译文。它包含几个句子。每个句子以句号结尾。"; List<Integer> originalSentencesIndex = findSentenceBeginnings(article); List<Integer> translationSentencesIndex = findTranslatedSentences(translation, article, originalSentencesIndex); String highlightedOriginalText = highlightSentences(article, originalSentencesIndex); String highlightedTranslationText = highlightSentences(translation, translationSentencesIndex); System.out.println(highlightedOriginalText); System.out.println(highlightedTranslationText); } private static List<Integer> findSentenceBeginnings(String text) { List<Integer> sentenceBeginnings = new ArrayList<>(); int i = 0; while (i < text.length()) { if (text.charAt(i) == '.') { sentenceBeginnings.add(i + 1); } i++; } return sentenceBeginnings; } private static List<Integer> findTranslatedSentences(String translation, String original, List<Integer> originalSentencesIndex) { List<Integer> translationSentencesIndex = new ArrayList<>(); for (int i = 0; i < originalSentencesIndex.size(); i++) { String originalSentence = original.substring(originalSentencesIndex.get(i) - 1); int index = translation.indexOf(originalSentence); if (index != -1) { translationSentencesIndex.add(index); } } return translationSentencesIndex; } private static String highlightSentences(String text, List<Integer> sentenceBeginnings) { StringBuilder highlightedText = new StringBuilder(); int lastSentenceEnd = 0; for (int i = 0; i < sentenceBeginnings.size(); i++) { int sentenceBeginning = sentenceBeginnings.get(i); highlightedText.append(text.substring(lastSentenceEnd, sentenceBeginning)); highlightedText.append("<b>"); int sentenceEnd = i == sentenceBeginnings.size() - 1 ? text.length() : sentenceBeginnings.get(i + 1); highlightedText.append(text.substring(sentenceBeginning, sentenceEnd)); highlightedText.append("</b>"); lastSentenceEnd = sentenceEnd; } return highlightedText.toString(); } } ``` 在上面的代码中,我们首先将原文和译文存储到两个字符串中。然后,我们使用findSentenceBeginnings方法查找原文中每个句子的开头位置,并将它们存储到一个List中。接下来,我们使用findTranslatedSentences方法在译文中查找对应的句子,并将它们的开头位置存储到另一个List中。最后,我们使用highlightSentences方法将原文和译文中对应的句子用HTML的<b>标签标记出来,以示区分。 值得注意的是,上面的代码只是一个简单的实现,还有很多细节需要处理,如句子中可能包含逗号、问号等标点符号,或者原文和译文中的句子可能存在微小的差异等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值