V8是谷歌开源的一个高性能JavaScript引擎

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了V8是谷歌开源的一个高性能JavaScript引擎相关的知识,希望对你有一定的参考价值。

  V8是谷歌开源的一个高性能javascript引擎,用 C++ 实现,并用在谷歌的开源浏览器Chrome里。
  
  为什么V8非常快,哪种方案让V8达到这种速度?发现其中秘密是一件有趣的事情。
  
  面向对象、设计模式与性能
  
  有些C/C++开发者有些奇怪的观念。他们认为使用面向对象和设计模式会降低程序的性能。但V8证明了这种观念是错误的。V8的实现使用了许多设计模式,但依然非常高效。
  
  下面列出V8中使用的两个模式:
  
  工厂模式
  
  当Javascript引擎执行一个脚本时,引擎为遇到的每个变量、函数或数组都创建一个实例。JSObject是所有这些对象的父对象。
  
  下面列出了所有继承自JSObject的类:
  
  V8实现了一个工厂类来创建这些对象,该类中的Factory::NewJsObject就是用来创建这些对象的。
  
  下面列出了所有使用该类/方法的方法。
  
  V8引擎中的类并没有直接使用这个工厂类,而是添加了另一层封装,通过Heap类调用该工厂类。
  
  访问者模式:
  
  维基百科上这样解释观察者模式:
  
  观察者设计模式是将算法和算法处理的对象分开的一种方式。这种分离可以在不修改结构本身的情况下,将新的操作添加到已有的对象结构上。这是一条遵循open/closed准则的方式。
  
  与工厂模式相似,访问者模式也为实现添加了封装层。这样让其代码更加可读且可维护。
  
  V8源码中许多类都实现了访问者模式。
  
  即使V8开发者必须优化执行效率,他们也不在乎添加到代码中的封装层。使用设计模式和添加一些C++的机制会增加一些封装,所以的确会对效率有影响。但这对效率的影响仅占一小部分,更多的影响来自该应用使用的设计决策。
  
  V8中针对执行效率方面的设计决策
  
  1. 隐藏类和快速属性访问。
  
  JavaScript是一种动态编程语言:可以在对象运行时为对象添加或删除熟悉。这意味着很容易改变对象的属性。
  
  JSFunction和JSValue的父类都是JSObject,JSFunction用来表示一个javascript函数,JSValue用来表示一个javascript值。但没有继承自JSObject的类,用以表示Function或Value这样的Class。许多JavaScript引擎使用词典类型的数据结构来存储这些对象的熟悉,访问每个属性都需要动态查找并解析属性在内存中的位置。
  
  这种方式导致JavaScript在访问对象变量的属性时,比在Java或Smalltalk中要慢。在这些语言中,实列变量分配的位置是固定的,即由编译器根据对象的类定义中的布局,在该对象在内存中的位置加上固定的偏移位置。因此访问这些属性仅仅是内存上的读取或存储,而这种操作通常只需一条指令。
  
  V8使用隐藏类概念来降低访问JavaScript属性所消耗的时间。V8不使用动态查询来访问属性,而是在幕后创建隐藏类。
  
  2. 动态生产机器码
  
  在首次执行时,V8就将JavaScript源码直接编译成机器码,没有中间字节码,没有解释器。属性访问由内联的缓存代码处理,V8执行时可能会有其他机器指令修改这些缓存代码。
  
  3. 高效的垃圾收集器
  
  在执行过程中,V8会重新获得废弃对象的内存,即垃圾回收。为了保证拥有较快的对象分类、较短的垃圾回收停顿,以及没有内存碎片。V8使用了停顿、分代、精确垃圾回收器。这意味着V8使用了:
  #include <stdio.h>
#include <time.h>
#include <opencv2/opencv.hpp>
#include <opencv/cv.h>
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>
#include <io.h>

using namespace std;
using namespace cv;

void getFiles( string path, vector<string>& files);
void getBubble(Mat& trainingImages, vector<int>& trainingLabels);
void getNoBubble(Mat& trainingImages, vector<int>& trainingLabels);

int main()
{
//获取训练数据
Mat classes;
Mat trainingData;
Mat trainingImages;
vector<int> trainingLabels;
getBubble(trainingImages, trainingLabels);
getNoBubble(trainingImages, trainingLabels);
Mat(trainingImages).copyTo(trainingData);
trainingData.convertTo(trainingData, CV_32FC1);
Mat(trainingLabels).copyTo(classes);
//配置SVM训练器参数
CvSVMParams SVM_params;
SVM_params.svm_type = CvSVM::C_SVC;
SVM_params.kernel_type = CvSVM::LINEAR;
SVM_params.degree = 0;
SVM_params.gamma = 1;
SVM_params.coef0 = 0;
SVM_params.C = 1;
SVM_params.nu = 0;
SVM_params.p = 0;
SVM_params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 1000, 0.01);
//训练
CvSVM svm;
svm.train(trainingData, classes, Mat(www.huachengjpt.com), Mat(), SVM_params);
//保存模型
svm.save("svm.xml");
cout<<"训练好了!!!"<<endl;
getchar();
return 0;
}
void getFiles( string path, vector<string>& files )
{
long hFile = 0;
struct _finddata_t www.8555388.cn/ fileinfo;
string p;
if((hFile = _findfirst(p.assign(path).append(www.yibaoyule1.com"\\*").c_str(),&fileinfo)) != -1)
{
do
{
if((fileinfo.attrib & _A_SUBDIR))
  在垃圾回收循环期间停止程序的执行。
  
  在大多数垃圾循环中,只处理对象堆的一部分。这最大化降低了停顿对应用的影响。
  
  记录所有对象和指针在内存中的位置,避免了将对象作为指针识别而导致的内存泄漏。
  
  结论:
  
  出于效率因素而不使用面向对象或设计模式,这是一个错误的观念。这样只会获得数毫秒的优化,却失去了代码的可读性和可维护性。

以上是关于V8是谷歌开源的一个高性能JavaScript引擎的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 引擎「V8」发布 8.0 版本,内存占用量大幅下降

什么是Google V8 JavaScript引擎

图解Google V8,搞懂 JavaScript 执行逻辑

Chrome V8基本介绍

V8 JavaScript引擎研究高性能探秘

初学J2V8