検索
ホームページウェブフロントエンドjsチュートリアルFunction.apply()_javascript のパラメータ配列を使用して JavaScript プログラムのパフォーマンスを向上させるヒント

我們再來聊聊Function.apply() 在提升程式效能方面的技巧。

我們先從 Math.max() 函數說起, Math.max後面可以接著任何個參數,最後回傳所有參數中的最大值。


alert(Math.max(5,8))  //8 
alert(Math.max(5,7,9,3,1,6))  //9 

但是在很多情況下,我們需要找出陣列中最大的元素。

var arr=[5,7,9,1] 
alert(Math.max(arr))  //  这样却是不行的。一定要这样写 
function getMax(arr){ 
  var arrLen=arr.length; 
  for(var i=0,ret=arr[0];i<arrLen;i++){ 
    ret=Math.max(ret,arr[i]);     
  } 
  return ret; 
}  

這樣寫麻煩而且低效。如果用 apply呢,看代碼:

function getMax2(arr){ 
  return Math.max.apply(null,arr) 
} 

兩段程式碼達到了同樣的目的,但是getMax2卻優雅,高效,簡潔得多。

看效能測驗:

getMax效能測試

var myArr=new Array() 
function fillRnd(arrLen){ //填入 arrLen个1-10的随机数字到数组 
  for(var i=0,arr=[];i<arrLen;i++){ 
    arr[i]=Math.ceil(Math.random()*10) 
  } 
  return arr 
} 
function getMax(arr){ 
  var arrLen=arr.length; 
  for(var i=0,ret=arr[0];i<arrLen;i++){ 
    ret=Math.max(ret,arr[i]);     
  } 
  return ret; 
} 
function getMax2(arr){ 
  return Math.max.apply(null,arr) 
} 
myArr=fillRnd(20*10000) //生成20万个随机数填到数组 
var t1=new Date() 
var max1=getMax(myArr) 
var t2=new Date() 
var max2=getMax2(myArr) 
var t3=new Date() 
if (max1!==max2) alert("error") 
alert([t3-t2,t2-t1])  //在我机器上 96,464 .不同的机器,结果可能有差异 

經過20萬個資料的比較, getMax2 時間為 96ms 而 getmax時間為464。 兩者相差5倍

再例如數組的push方法。

var arr1=[1,3,4]; 
var arr2=[3,4,5];

如果我們要把 arr2展開,然後一個一個追加到 arr1中去,最後讓 arr1=[1,3,4,3,4,5]

arr1.push(arr2) 顯然是不行的。 因為這樣做會得到 [1,3,4, [3,4,5] ] 

我們只能用一個循環去一個一個的push (當然也可以用 arr1.concat(arr2) 但是concat方法並沒有改變 arr1本身) 

var arrLen=arr2.length 
for(var i=0;i<arrLen;i++){ 
  arr1.push(arr2[i]) 
}

自從有了 Apply ,事情就變得如此簡單

Array.prototype.push.apply(arr1,arr2) 

附:如何最佳化JavaScript腳本的效能

隨著網路的發展,網路速度和機器速度的提高,越來越多的網站用到了豐富客戶端技術。而現在Ajax則是最受歡迎的一種方式。 JavaScript是一種解釋型語言,所以能無法達到和C/Java之類的水平,限制了它能在客戶端所做的事情,為了能改進他的性能,我想基於我以前給JavaScript做過的很多測試來談談自己的經驗,希望能幫助大家改進自己的JavaScript腳本效能。

語言層次方面

循環

循環是很常用的一個控制結構,大部分東西要依靠它來完成,在JavaScript中,我們可以使用for(;;),while(),for(in)三種循環,事實上,這三種迴圈中for(in)的效率極差,因為他需要查詢散列鍵,只要可以就應該盡量少用。 for(;;)和while迴圈的表現應該說基本(平常使用時)等價。

而事實上,如何使用這兩個循環,則有很大講究。我在測試中有些很有意思的情況,請見附錄。最後得出的結論是:

如果是循環變數遞增或遞減,不要單獨對循環變數賦值,應該在它最後一次讀取的時候使用嵌套的++或—操作符。

如果要與陣列的長度作比較,應該事先把陣列的length屬性放入一個局部變數中,減少查詢次數。

局部變數與全域變數

局部變數的速度要比全域變數的存取速度更快,因為全域變數其實是全域物件的成員,而局部變數是放在函數的堆疊當中的。

不使用Eval

使用eval相當於在運行時再次呼叫解釋引擎對內容進行運行,需要消耗大量時間。這時候使用JavaScript所支援的閉包可以實現函數模版(關於閉包的內容請參考函數式程式設計的內容)

減少物件查找

因為JavaScript的解釋性,所以a.b.c.d.e,需要進行至少4次查詢操作,先檢查a再檢查a中的b,再檢查b中的c,如此往下。所以如果這樣的表達式重複出現,只要可能,應該盡量少出現這樣的表達式,可以利用局部變量,把它放入一個臨時的地方進行查詢。

這一點可以和循環結合起來,因為我們常常要根據字串、數組的長度進行循環,而通常這個長度是不變的,比如每次查詢a.length,就要額外進行一個操作,而預先把var len=a.length,則少了一次查詢。

字串連線

如果是追加字串,最好使用s+=anotherStr操作,而不是要使用s=s+anotherStr。

如果要連接多個字串,應該少使用+=,如

s+=a;s+=b;s+=c;應該寫成
s+=a + b + c;而如果是收集字串,例如多次對同一個字串進行+=操作的話,最好使用一個快取。怎麼用呢?使用JavaScript數組來收集,最後使用join方法連接起來,如下

var buf = new Array();for(var i = 0; i < 100; i++){ buf.push(i.toString());}var all = buf.join("");类型转换

JavaScript は動的に型付けされる言語であり、変数の型を指定できないため、型変換は誰もが犯しやすい間違いです。

1. 数値を文字列に変換し、「" + 1 を使用します。見た目は少し悪くなりますが、実際には、パフォーマンスの点でこれが最も効率的です。
("" +) > String() > .toString()これは実際には、以下の「直接量」と多少似ていますが、コンパイル時に使用できる内部操作を使用して、実行時に使用されるユーザー操作よりも高速になるようにしてください。

String() は内部関数であるため非常に高速ですが、.toString() はプロトタイプ内の関数をクエリするため、正確なコピーを返すために new String() を使用するほど高速ではありません。

2. 浮動小数点数を整数に変換する場合、多くの人は parseInt() を使用することを好みますが、浮動小数点数と整数の間では変換されません。 Math.floor() または Math.round() を使用する必要があります。

また、セクション 2 のオブジェクト検索の問題とは異なり、Math は内部オブジェクトであるため、実際には Math.floor() はクエリ メソッドや呼び出し回数が少なく、最も高速です。

3. カスタム オブジェクトの場合、型変換用に toString() メソッドが定義されている場合は、メソッドがすべての可能性をテストした後に内部操作でオブジェクトの toString() を試行するため、明示的に toString() を呼び出すことをお勧めします。 String に変換できるかどうかを判断するため、このメソッドを直接呼び出す方が効率的です

直接量を使用する

実際、この影響は比較的小さいため無視できます。直接量を使用するとはどういう意味ですか? たとえば、JavaScript は配列を直接表現するために [param, param, param,...] を使用することをサポートしていました。以前は new Array(param, param,...) を使用していました。前者を使用するとエンジンによって直接解釈されますが、後者は配列の内部コンストラクターを呼び出す必要があるため、若干高速になります。


同様に、var foo = {} は var foo = new Object(); より高速で、var reg = /../; は var reg=new RegExp() より高速です。

文字列トラバーサル操作

置換や検索などの文字列のループ操作を実行するには、正規表現を使用する必要があります。これは、JavaScript 自体のループ速度が比較的遅く、正規表現の操作は C で書かれた API であり、パフォーマンスが低いためです。とても良い。

高度なオブジェクト

カスタムの高度なオブジェクトと Date および RegExp オブジェクトは、構築中に多くの時間を消費します。再利用できる場合は、キャッシュを使用する必要があります。

DOM 関連

HTML を挿入

多くの人は、JavaScript で document.write を使用してページのコンテンツを生成することを好みます。実際、これは効率が低くなります。HTML を直接挿入する必要がある場合は、div または span を指定するなどのコンテナー要素を見つけて、独自の HTML コードをページに挿入するように innerHTML を設定できます。

オブジェクトクエリ

[""] を使用してクエリを実行すると、.items() よりも高速になります。これは、.items() を呼び出すことでクエリと関数の呼び出しを追加するという前述のアイデアと同じです。

DOM ノードの作成

通常、文字列を使用して HTML を直接記述してノードを作成しますが、実際にはこれを行います

コードの正当性は保証できません

文字列の操作効率が低い

したがって、document.createElement() メソッドを使用する必要があります。また、ドキュメント内に既製のテンプレート ノードがある場合は、cloneNode() メソッドを使用する必要があります。これは、createElement() メソッドを使用した後、次の操作を行う必要があるためです。要素の属性を複数回設定する場合は、 cloneNode() を使用すると属性設定の数を減らすことができます。同様に、多数の要素を作成する必要がある場合は、最初にテンプレート ノードを準備する必要があります。


タイマー

常に実行されているコードを対象としている場合は、setTimeout ではなく setInterval を使用する必要があります。 setTimeout は毎回タイマーをリセットします。


その他

スクリプト エンジン

私のテストによると、JScript は現在基本的に更新されていないため、Microsoft の JScript の効率は、実行速度とメモリ管理の両方の点で Mozilla の Spidermonkey よりもはるかに悪いです。ただし、SpiderMonkey は ActiveXObject

を使用できません

ファイルの最適化

ファイルの最適化も非常に効果的な方法です。ローカルの場合は、すべてのスペースとコメントを削除し、コードを 1 行にまとめます。これは解析速度ではなくダウンロード速度であることに注意してください。スペースは解釈や実行速度には影響しません。

概要

この記事は、JavaScript の実行パフォーマンスを向上させるために私が見つけた JavaScript プログラミングの方法のいくつかをまとめたものです。実際、これらの経験はいくつかの原則に基づいています。


すぐに利用できるものを使用する方が高速です。たとえば、ローカル変数はグローバル変数よりも高速であり、直接変数は実行時にオブジェクトを構築するよりも高速です。


複数のクエリが必要なクエリを最初にキャッシュするなど、実行数をできるだけ減らします。


文字列リンクなど、組み込みの言語機能をできる限り使用します。


これらの API はコンパイルされたバイナリコードであり、実行効率が高いため、システムが提供する API をできるだけ使用してください


同时,一些基本的算法上的优化,同样可以用在JavaScript中,比如运算结构的调整,这里就不再赘述了。但是由于JavaScript是解释型的,一般不会在运行时对字节码进行优化,所以这些优化仍然是很重要的。

当然,其实这里的一些技巧同样使用在其他的一些解释型语言中,大家也可以进行参考。

由于是以前做过的测试,测试代码已经不全,我补充了一部分如下:

var print; 
if(typeof document != "undefined" ){ 
  print = function(){ 
document.write(arguments[0]); 
} 
}else if(typeof WScript != "undefined" ){ 
  print = function(){ 
    WScript.Echo(arguments[0],arguments[1],arguments[2]); 
  } 
} 
function empty(){ 
} 
function benchmark(f){ 
  var i = 0; 
  var start = (new Date()).getTime(); 
  while(i < pressure){ 
    f(i++); 
  } 
  var end = (new Date()).getTime(); 
  WScript.Echo(end-start); 
} 
/* 
i=0 
start = (new Date()).getTime(); 
while(i < 60000){ 
  c = [i,i,i,i,i,i,i,i,i,i]; 
  i++; 
} 
end = (new Date()).getTime(); 
WScript.Echo(end-start); 
i=0 
start = (new Date()).getTime(); 
while(i < 60000){ 
  c = new Array(i,i,i,i,i,i,i,i,i,i); 
  i++; 
} 
var end = (new Date()).getTime(); 
WScript.Echo(end-start); 
*/ 
function internCast(i){ 
  return "" + i; 
} 
function StringCast(i){ 
  return String(i) 
} 
function newStringCast(i){ 
  return new String(i) 
} 
function toStringCast(i){ 
  return i.toString(); 
} 
function ParseInt(){ 
  return parseInt(j); 
} 
function MathFloor(){ 
  return Math.floor(j); 
} 
function Floor(){ 
  return floor(j); 
} 
var pressure = 50000; 
var a = ""; 
var floor = Math.floor; 
j = 123.123; 
print("-------------\nString Conversion Test"); 
print("The empty:", benchmark(empty)); 
print("intern:", benchmark(internCast)); 
print("String:"); 
benchmark(StringCast); 
print("new String:"); 
benchmark(newStringCast); 
print("toString:"); 
benchmark(toStringCast); 
print("-------------\nFloat to Int Conversion Test"); 
print("parseInt"); 
benchmark(ParseInt); 
print("Math.floor"); 
benchmark(MathFloor); 
print("floor") 
benchmark(Floor); 
function newObject(){ 
  return new Object(); 
} 
function internObject(){ 
  return {}; 
} 
print("------------\nliteral Test"); 
print("runtime new object", benchmark(newObject)); 
print("literal object", benchmark(internObject));  

附录2

代码1:

for(var i=0;i<100;i++){ 
    arr[i]=0; 
  }

代码2:

 var i = 0; 
  while(i < 100){ 
    arr[i++]=0; 
  } 

 代码3: 

 var i = 0; 
  while(i < 100){ 
    arr[i]=0; 
    i++; 
  }

 在firefox下测试这两段代码,结果是代码2优于代码1和3,而代码1一般优于代码3,有时会被代码3超过;而在IE 6.0下,测试压力较大的时候(如测试10000次以上)代码2和3则有时候优于代码1,有时候就会远远落后代码1,而在测试压力较小(如5000次),则代码2>代码3>代码1。

代码4:

var i = 0; 
  var a; 
  while(i < 100){ 
    a = 0; 
    i++; 
  } 

代码5:

 var a; 
  for(var i=0;i<100;i++){ 
    a = 0; 
  } 

上面两段代码在Firefox和IE下测试结果都是性能接近的。

代码6:

  var a; 
  var i=0; 
  while(i<100){ 
    a=i; 
    i++; 
  } 

代码7:

 var a; 
  var i=0; 
  while(i<100){ 
    a=i++; 
  } 

代码8:

 var a; 
  for(var i=0;i<100;i++){ 
    a = i; 
  } 

代码9:

 var a; 
  for(var i=0;i<100;){ 
    a = i++; 
  } 

这四段代码在Firefox下6和8的性能接近,7和9的性能接近,而6, 8

最后我们来看一下空循环

代码10: 

for(var i=0;i<100;i++){  } 

代码11:

  var i; 
  while(i<100){    i++;  } 

最后的测试出现了神奇的结果,Firefox下代码10所花的时间与代码11所花的大约是24:1。所以它不具备参考价值,于是我没有放在一开始给大家看。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScriptの文字列文字を交換しますJavaScriptの文字列文字を交換しますMar 11, 2025 am 12:07 AM

JavaScript文字列置換法とFAQの詳細な説明 この記事では、javaScriptの文字列文字を置き換える2つの方法について説明します:内部JavaScriptコードとWebページの内部HTML。 JavaScriptコード内の文字列を交換します 最も直接的な方法は、置換()メソッドを使用することです。 str = str.replace( "find"、 "置換"); この方法は、最初の一致のみを置き換えます。すべての一致を置き換えるには、正規表現を使用して、グローバルフラグGを追加します。 str = str.replace(/fi

カスタムGoogle検索APIセットアップチュートリアルカスタムGoogle検索APIセットアップチュートリアルMar 04, 2025 am 01:06 AM

このチュートリアルでは、カスタムGoogle検索APIをブログまたはWebサイトに統合する方法を示し、標準のWordPressテーマ検索関数よりも洗練された検索エクスペリエンスを提供します。 驚くほど簡単です!検索をyに制限することができます

独自のAjax Webアプリケーションを構築します独自のAjax Webアプリケーションを構築しますMar 09, 2025 am 12:11 AM

それで、あなたはここで、Ajaxと呼ばれるこのことについてすべてを学ぶ準備ができています。しかし、それは正確には何ですか? Ajaxという用語は、動的でインタラクティブなWebコンテンツを作成するために使用されるテクノロジーのゆるいグループ化を指します。 Ajaxという用語は、もともとJesse Jによって造られました

例JSONファイルの例例JSONファイルの例Mar 03, 2025 am 12:35 AM

この記事シリーズは、2017年半ばに最新の情報と新鮮な例で書き直されました。 このJSONの例では、JSON形式を使用してファイルに単純な値を保存する方法について説明します。 キー価値ペア表記を使用して、あらゆる種類を保存できます

10 jQuery構文蛍光物10 jQuery構文蛍光物Mar 02, 2025 am 12:32 AM

コードプレゼンテーションを強化する:開発者向けの10個の構文蛍光物 ウェブサイトやブログでコードスニペットを共有することは、開発者にとって一般的な慣行です。 適切な構文ハイライターを選択すると、読みやすさと視覚的な魅力を大幅に改善できます。 t

8見事なjQueryページレイアウトプラグイン8見事なjQueryページレイアウトプラグインMar 06, 2025 am 12:48 AM

楽なWebページレイアウトのためにjQueryを活用する:8本質的なプラグイン jQueryは、Webページのレイアウトを大幅に簡素化します。 この記事では、プロセスを合理化する8つの強力なjQueryプラグイン、特に手動のウェブサイトの作成に役立ちます

10 JavaScript&JQuery MVCチュートリアル10 JavaScript&JQuery MVCチュートリアルMar 02, 2025 am 01:16 AM

この記事では、JavaScriptとJQuery Model-View-Controller(MVC)フレームワークに関する10を超えるチュートリアルの厳選された選択を紹介します。これは、新年にWeb開発スキルを向上させるのに最適です。 これらのチュートリアルは、Foundatioのさまざまなトピックをカバーしています

&#x27; this&#x27; JavaScriptで?&#x27; this&#x27; JavaScriptで?Mar 04, 2025 am 01:15 AM

コアポイント これは通常、メソッドを「所有」するオブジェクトを指しますが、関数がどのように呼び出されるかに依存します。 現在のオブジェクトがない場合、これはグローバルオブジェクトを指します。 Webブラウザでは、ウィンドウで表されます。 関数を呼び出すと、これはグローバルオブジェクトを維持しますが、オブジェクトコンストラクターまたはそのメソッドを呼び出すとき、これはオブジェクトのインスタンスを指します。 call()、apply()、bind()などのメソッドを使用して、このコンテキストを変更できます。これらのメソッドは、与えられたこの値とパラメーターを使用して関数を呼び出します。 JavaScriptは優れたプログラミング言語です。数年前、この文はそうでした

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境