V8 இன்ஜின் இன்லைன் கேச்சிங் மற்றும் பல்லுருவத்துவ மேம்படுத்தல் பற்றி ஆழமாகப் புரிந்துகொள்ளுங்கள். உயர்-செயல்திறன் பயன்பாடுகளுக்கு ஜாவாஸ்கிரிப்ட் டைனமிக் ப்ராப்பர்ட்டி அணுகலை எவ்வாறு கையாள்கிறது என்பதை அறியுங்கள்.
செயல்திறனைத் திறத்தல்: V8 இன் பல்லுருவ இன்லைன் கேச்சிங் ஒரு ஆழமான பார்வை
வலைத்தளங்களின் எங்கும் நிறைந்த மொழியான ஜாவாஸ்கிரிப்ட், பெரும்பாலும் மாயாஜாலமாக பார்க்கப்படுகிறது. இது டைனமிக், நெகிழ்வானது, மற்றும் ஆச்சரியப்படும் வகையில் வேகமானது. இந்த வேகம் தற்செயலானது அல்ல; இது கூகிளின் V8 போன்ற ஜாவாஸ்கிரிப்ட் இன்ஜின்களில் (Chrome, Node.js மற்றும் எண்ணற்ற பிற தளங்களுக்குப் பின்னால் உள்ள சக்தி) பல பத்தாண்டுகளின் இடைவிடாத பொறியியல் முயற்சியின் விளைவாகும். V8 இன் திறனை அதிகரிக்கும் மிக முக்கியமான, ஆனால் பெரும்பாலும் தவறாகப் புரிந்துகொள்ளப்பட்ட மேம்படுத்தல்களில் ஒன்று இன்லைன் கேச்சிங் (IC), குறிப்பாக அது பல்லுருவத்துவத்தை எவ்வாறு கையாள்கிறது என்பது.
பல டெவலப்பர்களுக்கு, V8 இன்ஜினின் உள் செயல்பாடுகள் ஒரு கருப்புப் பெட்டி போன்றவை. நாம் குறியீட்டை எழுதுகிறோம், அது இயங்குகிறது—பொதுவாக மிக விரைவாக. ஆனால் அதன் செயல்திறனைக் கட்டுப்படுத்தும் கொள்கைகளைப் புரிந்துகொள்வது நாம் குறியீட்டை எழுதும் முறையை மாற்றும், தற்செயலான செயல்திறனில் இருந்து நோக்கமான மேம்படுத்தலுக்கு நம்மை நகர்த்தும். இந்த கட்டுரை V8 இன் மிகச் சிறந்த உத்திகளில் ஒன்றைப் பற்றி வெளிப்படுத்தும்: டைனமிக் ஆப்ஜெக்ட்கள் நிறைந்த உலகில் ப்ராப்பர்ட்டி அணுகலை மேம்படுத்துதல். நாம் மறைக்கப்பட்ட வகுப்புகள், இன்லைன் கேச்சிங்கின் மாயாஜாலம் மற்றும் மோனோமார்பிசம், பல்லுருவத்துவம் மற்றும் மெகாமார்பிசம் ஆகிய முக்கியமான நிலைகளை ஆராய்வோம்.
முக்கிய சவால்: ஜாவாஸ்கிரிப்டின் டைனமிக் தன்மை
தீர்வைப் பாராட்ட, நாம் முதலில் சிக்கலைப் புரிந்துகொள்ள வேண்டும். ஜாவாஸ்கிரிப்ட் ஒரு டைனமிக்-டைப் செய்யப்பட்ட மொழி. அதாவது, ஜாவா அல்லது C++ போன்ற ஸ்டாட்டிக்கலி-டைப் செய்யப்பட்ட மொழிகளைப் போலல்லாமல், ஒரு மாறியின் வகை மற்றும் ஒரு ஆப்ஜெக்ட்டின் கட்டமைப்பு இயக்க நேரத்தில் (runtime) மட்டுமே அறியப்படும். நீங்கள் ஒரு ஆப்ஜெக்டை உருவாக்கி, அதன் பண்புகளை உடனேயே சேர்க்கலாம், மாற்றலாம் அல்லது நீக்கலாம்.
இந்த எளிய குறியீட்டைக் கவனியுங்கள்:
const item = {};
item.name = "Book";
item.price = 19.99;
C++ போன்ற ஒரு மொழியில், ஒரு ஆப்ஜெக்ட்டின் 'வடிவம்' (அதன் வகுப்பு) தொகுக்கும் நேரத்தில் (compile time) வரையறுக்கப்படுகிறது. ஆப்ஜெக்ட்டின் தொடக்கத்திலிருந்து ஒரு நிலையான ஆஃப்செட் ஆக `name` மற்றும் `price` பண்புகள் நினைவகத்தில் எங்கு அமைந்துள்ளன என்பதை கம்பைலர் சரியாக அறியும். `item.price` ஐ அணுகுவது ஒரு எளிய, நேரடி நினைவக அணுகல் செயல்பாடு—ஒரு CPU செயல்படுத்தக்கூடிய வேகமான கட்டளைகளில் ஒன்று.
ஜாவாஸ்கிரிப்டில், இன்ஜின் இந்த அனுமானங்களைச் செய்ய முடியாது. ஒரு எளிய செயல்படுத்தல் ஒவ்வொரு ஆப்ஜெக்ட்டையும் ஒரு அகராதி அல்லது ஹாஷ் மேப் போல நடத்த வேண்டியிருக்கும். `item.price` ஐ அணுக, இன்ஜின் `item` ஆப்ஜெக்ட்டின் உள் ப்ராப்பர்ட்டி பட்டியலில் "price" என்ற key-க்கான ஒரு சரத் தேடலை (string lookup) செய்ய வேண்டியிருக்கும். ஒரு சுழற்சிக்குள் ஒரு ப்ராப்பர்ட்டியை அணுகும் ஒவ்வொரு முறையும் இந்தத் தேடல் நடந்தால், நமது பயன்பாடுகள் நின்றுவிடும். இது V8 தீர்க்க உருவாக்கப்பட்ட அடிப்படை செயல்திறன் சவால்.
வரிசையின் அடித்தளம்: மறைக்கப்பட்ட வகுப்புகள் (வடிவங்கள்)
இந்த டைனமிக் குழப்பத்தை அடக்கும் V8 இன் முதல் படி, வெளிப்படையாக வரையறுக்கப்படாத இடத்தில் ஒரு அமைப்பை உருவாக்குவதாகும். இது மறைக்கப்பட்ட வகுப்புகள் (SpiderMonkey போன்ற பிற இன்ஜின்களில் 'வடிவங்கள்' என்றும், V8 இன் உள் சொற்களில் 'வரைபடங்கள்' என்றும் குறிப்பிடப்படுகிறது) எனப்படும் ஒரு கருத்து மூலம் இதைச் செய்கிறது. ஒரு மறைக்கப்பட்ட வகுப்பு என்பது ஒரு ஆப்ஜெக்ட்டின் அமைப்பை விவரிக்கும் ஒரு உள் தரவு அமைப்பு ஆகும், இதில் அதன் ப்ராப்பர்ட்டிகளின் பெயர்கள் மற்றும் அவற்றின் மதிப்புகள் நினைவகத்தில் எங்கு காணப்படுகின்றன என்பதும் அடங்கும்.
முக்கிய நுண்ணறிவு என்னவென்றால், ஜாவாஸ்கிரிப்ட் ஆப்ஜெக்ட்கள் டைனமிக் இருக்க முடியும் என்றாலும், அவை பெரும்பாலும் இருப்பதில்லை. டெவலப்பர்கள் ஒரே கட்டமைப்பைக் கொண்ட ஆப்ஜெக்ட்களை மீண்டும் மீண்டும் உருவாக்குகிறார்கள். V8 இந்த முறையைப் பயன்படுத்துகிறது.
நீங்கள் ஒரு புதிய ஆப்ஜெக்டை உருவாக்கும்போது, V8 அதற்கு ஒரு அடிப்படை மறைக்கப்பட்ட வகுப்பை ஒதுக்குகிறது, அதை நாம் `C0` என்று அழைப்போம்.
const p1 = {}; // p1 has Hidden Class C0 (empty)
ஒவ்வொரு முறையும் நீங்கள் ஆப்ஜெக்ட்டில் ஒரு புதிய ப்ராப்பர்ட்டியைச் சேர்க்கும்போது, V8 முந்தைய ஒன்றிலிருந்து 'மாறும்' ஒரு புதிய மறைக்கப்பட்ட வகுப்பை உருவாக்குகிறது. புதிய மறைக்கப்பட்ட வகுப்பு ஆப்ஜெக்ட்டின் புதிய வடிவத்தை விவரிக்கிறது.
p1.x = 10; // V8 creates a new Hidden Class C1, which is based on C0 + property 'x'.
// A transition is recorded: C0 + 'x' -> C1.
// p1's Hidden Class is now C1.
p1.y = 20; // V8 creates another Hidden Class C2, based on C1 + property 'y'.
// A transition is recorded: C1 + 'y' -> C2.
// p1's Hidden Class is now C2.
இது ஒரு மாறுதல் மரத்தை உருவாக்குகிறது. இப்போது, இங்குதான் மாயாஜாலம் உள்ளது: நீங்கள் மற்றொரு ஆப்ஜெக்டை உருவாக்கி, அதே பண்புகளை அதே வரிசையில் சேர்த்தால், V8 இந்த மாறுதல் பாதையையும் இறுதி மறைக்கப்பட்ட வகுப்பையும் மீண்டும் பயன்படுத்தும்.
const p2 = {}; // p2 starts with C0
p2.x = 30; // V8 follows the existing transition (C0 + 'x') and assigns C1 to p2.
p2.y = 40; // V8 follows the next transition (C1 + 'y') and assigns C2 to p2.
இப்போது, `p1` மற்றும் `p2` ஆகிய இரண்டும் ஒரே மறைக்கப்பட்ட வகுப்பான `C2` ஐப் பகிர்ந்து கொள்கின்றன. இது நம்பமுடியாத முக்கியமானது. மறைக்கப்பட்ட வகுப்பு `C2` ஆனது `x` பண்பு ஆஃப்செட் 0 இல் (உதாரணமாக) மற்றும் `y` பண்பு ஆஃப்செட் 1 இல் உள்ளது என்ற தகவலைக் கொண்டுள்ளது. இந்த கட்டமைப்பு தகவலைப் பகிர்வதன் மூலம், V8 இப்போது இந்த ஆப்ஜெக்ட்களில் உள்ள பண்புகளை அகராதி தேடலைச் செய்யாமல், ஸ்டாட்டிக் மொழி வேகத்திற்கு நெருக்கமான வேகத்தில் அணுக முடியும். அதற்கு ஆப்ஜெக்ட்டின் மறைக்கப்பட்ட வகுப்பைக் கண்டுபிடித்து, பின்னர் கேச் செய்யப்பட்ட ஆஃப்செட்டைப் பயன்படுத்தினால் போதும்.
வரிசை ஏன் முக்கியம்
நீங்கள் பண்புகளை வேறு வரிசையில் சேர்த்தால், நீங்கள் ஒரு வேறுபட்ட மாறுதல் பாதையையும் ஒரு வேறுபட்ட இறுதி மறைக்கப்பட்ட வகுப்பையும் உருவாக்குவீர்கள்.
const objA = { x: 1, y: 2 }; // Path: C0 -> C1(x) -> C2(x,y)
const objB = { y: 2, x: 1 }; // Path: C0 -> C3(y) -> C4(y,x)
`objA` மற்றும் `objB` ஒரே பண்புகளைக் கொண்டிருந்தாலும், அவை உள்நாட்டில் வெவ்வேறு மறைக்கப்பட்ட வகுப்புகளைக் கொண்டுள்ளன (`C2` vs `C4`). இது அடுத்த மேம்படுத்தல் அடுக்குக்கு ஆழமான தாக்கங்களை ஏற்படுத்துகிறது: இன்லைன் கேச்சிங்.
வேக பூஸ்டர்: இன்லைன் கேச்சிங் (IC)
மறைக்கப்பட்ட வகுப்புகள் வரைபடத்தை வழங்குகின்றன, ஆனால் இன்லைன் கேச்சிங் அதை பயன்படுத்தும் அதிவேக வாகனம் ஆகும். IC என்பது ஒரு கால் சைட்—உங்கள் குறியீட்டில் ஒரு செயல்பாடு (ப்ராப்பர்ட்டி அணுகல் போன்றது) நிகழும் ஒரு குறிப்பிட்ட இடம்—முந்தைய செயல்பாடுகளின் முடிவுகளை கேச் செய்ய V8 உட்பொதிக்கும் ஒரு குறியீடு ஆகும்.
பல முறை செயல்படுத்தப்படும் ஒரு செயல்பாடு, 'ஹாட்' செயல்பாடு என்று அழைக்கப்படுவது, அதைக் கருத்தில் கொள்வோம்:
function getX(obj) {
return obj.x; // This is our call site
}
for (let i = 0; i < 10000; i++) {
getX({ x: i, y: i + 1 });
}
இங்கு `obj.x` இல் IC எவ்வாறு செயல்படுகிறது என்பது இங்கே:
- முதல் செயல்படுத்தல் (துவக்கப்படாதது): முதல் முறையாக `getX` அழைக்கப்படும்போது, IC க்கு எந்த தகவலும் இருக்காது. அது உள்வரும் ஆப்ஜெக்ட்டில் 'x' ப்ராப்பர்ட்டியைக் கண்டறிய ஒரு முழுமையான, மெதுவான தேடலைச் செய்கிறது. இந்த செயல்முறையின் போது, அது ஆப்ஜெக்ட்டின் மறைக்கப்பட்ட வகுப்பையும் 'x' இன் ஆஃப்செட்டையும் கண்டறிகிறது.
- முடிவை கேச் செய்தல்: IC இப்போது தன்னை மாற்றியமைக்கிறது. அது தான் பார்த்த மறைக்கப்பட்ட வகுப்பையும், 'x' க்கான தொடர்புடைய ஆஃப்செட்டையும் கேச் செய்கிறது. IC இப்போது ஒரு 'மோனோமார்பிக்' நிலையில் உள்ளது.
- அடுத்தடுத்த செயல்படுத்தல்கள்: இரண்டாவது (மற்றும் அடுத்தடுத்த) அழைப்புகளில், IC ஒரு அதிவேக சரிபார்ப்பைச் செய்கிறது: "உள்வரும் ஆப்ஜெக்ட் நான் கேச் செய்த அதே மறைக்கப்பட்ட வகுப்பைக் கொண்டுள்ளதா?". ஆம் என்றால், அது தேடலை முழுவதுமாகத் தவிர்த்து, கேச் செய்யப்பட்ட ஆஃப்செட்டை நேரடியாகப் பயன்படுத்தி மதிப்பைப் பெறுகிறது. இந்த சரிபார்ப்பு பெரும்பாலும் ஒரு ஒற்றை CPU கட்டளை ஆகும்.
இந்த செயல்முறை ஒரு மெதுவான, டைனமிக் தேடலை, ஒரு ஸ்டாட்டிக்கலி-தொகுக்கப்பட்ட மொழியில் உள்ளதைப் போன்ற வேகமான ஒரு செயல்பாடாக மாற்றுகிறது. செயல்திறன் ஆதாயம் மிக அதிகம், குறிப்பாக சுழற்சிகளுக்குள் உள்ள குறியீடுகளுக்கு அல்லது அடிக்கடி அழைக்கப்படும் செயல்பாடுகளுக்கு.
உண்மையைக் கையாளுதல்: ஒரு இன்லைன் கேச்சின் நிலைகள்
உலகம் எப்போதும் அவ்வளவு எளிமையானது அல்ல. ஒரு ஒற்றை கால் சைட் அதன் வாழ்நாளில் வெவ்வேறு வடிவங்களைக் கொண்ட ஆப்ஜெக்ட்களை எதிர்கொள்ளக்கூடும். இங்குதான் பல்லுருவத்துவம் வருகிறது. இன்லைன் கேச் பல நிலைகள் வழியாக மாறுவதன் மூலம் இந்த யதார்த்தத்தை கையாள வடிவமைக்கப்பட்டுள்ளது.
1. மோனோமார்பிசம் (சரியான நிலை)
மோனோ = ஒன்று. மார்ப் = வடிவம்.
ஒரு மோனோமார்பிக் IC என்பது ஒரு வகை மறைக்கப்பட்ட வகுப்பை மட்டுமே பார்த்தது. இது வேகமான மற்றும் மிகவும் விரும்பத்தக்க நிலை.
function getX(obj) {
return obj.x;
}
// All objects passed to getX have the same shape.
// The IC at 'obj.x' will be monomorphic and incredibly fast.
getX({ x: 1, y: 2 });
getX({ x: 10, y: 20 });
getX({ x: 100, y: 200 });
இந்தச் சூழலில், அனைத்து ஆப்ஜெக்ட்களும் `x` மற்றும் பின்னர் `y` பண்புகளுடன் உருவாக்கப்படுகின்றன, எனவே அவை அனைத்தும் ஒரே மறைக்கப்பட்ட வகுப்பைப் பகிர்ந்து கொள்கின்றன. `obj.x` இல் உள்ள IC இந்த ஒற்றை வடிவத்தையும் அதன் தொடர்புடைய ஆஃப்செட்டையும் கேச் செய்கிறது, இதன் விளைவாக அதிகபட்ச செயல்திறன் கிடைக்கும்.
2. பல்லுருவத்துவம் (பொதுவான வழக்கு)
பாலி = பல. மார்ப் = வடிவம்.
ஒரு செயல்பாடு வெவ்வேறு, ஆனால் வரையறுக்கப்பட்ட வடிவங்களைக் கொண்ட ஆப்ஜெக்ட்களுடன் வேலை செய்ய வடிவமைக்கப்படும்போது என்ன நடக்கும்? உதாரணமாக, ஒரு `render` செயல்பாடு ஒரு `Circle` அல்லது `Square` ஆப்ஜெக்டை ஏற்றுக்கொள்ளலாம்.
function getArea(shape) {
// What happens at this call site?
return shape.width * shape.height;
}
const square = { type: 'square', width: 100, height: 100 };
const rectangle = { type: 'rect', width: 200, height: 50 };
getArea(square); // First call
getArea(rectangle); // Second call
V8 இன் பல்லுருவ IC இதை எவ்வாறு கையாள்கிறது என்பது இங்கே:
- அழைப்பு 1 (`getArea(square)`): `shape.width` க்கான IC மோனோமார்பிக் ஆகிறது. அது `square` இன் மறைக்கப்பட்ட வகுப்பையும் `width` ப்ராப்பர்ட்டியின் ஆஃப்செட்டையும் கேச் செய்கிறது.
- அழைப்பு 2 (`getArea(rectangle)`): IC `rectangle` இன் மறைக்கப்பட்ட வகுப்பை சரிபார்க்கிறது. அது கேச் செய்யப்பட்ட `square` வகுப்பிலிருந்து வேறுபட்டது. கைவிடுவததற்குப் பதிலாக, IC ஒரு பல்லுருவ நிலைக்கு மாறுகிறது. அது இப்போது பார்த்த மறைக்கப்பட்ட வகுப்புகள் மற்றும் அவற்றின் தொடர்புடைய ஆஃப்செட்களின் ஒரு சிறிய பட்டியலைப் பராமரிக்கிறது. அது `rectangle` இன் மறைக்கப்பட்ட வகுப்பையும் `width` ஆஃப்செட்டையும் இந்தப் பட்டியலில் சேர்க்கிறது.
- அடுத்தடுத்த அழைப்புகள்: `getArea` மீண்டும் அழைக்கப்படும்போது, IC உள்வரும் ஆப்ஜெக்ட்டின் மறைக்கப்பட்ட வகுப்பு அதன் அறியப்பட்ட வடிவங்களின் பட்டியலில் உள்ளதா என்பதைச் சரிபார்க்கிறது. அது ஒரு பொருத்தத்தைக் கண்டறிந்தால் (எ.கா., மற்றொரு `square`), அது தொடர்புடைய ஆஃப்செட்டைப் பயன்படுத்துகிறது.
ஒரு பல்லுருவ அணுகல், ஒரு மோனோமார்பிக் அணுகலை விட சற்று மெதுவாக இருக்கும், ஏனெனில் அது ஒன்றுக்கு பதிலாக பல வடிவங்களின் பட்டியலை சரிபார்க்க வேண்டும். இருப்பினும், இது முழுமையான, கேச் செய்யப்படாத தேடலை விட மிக வேகமாக இருக்கும். ஒரு IC எவ்வளவு பல்லுருவமாக மாற முடியும் என்பதற்கு V8 ஒரு வரம்பைக் கொண்டுள்ளது—பொதுவாக 4 முதல் 5 வெவ்வேறு வடிவங்கள் வரை. இது ஒரு செயல்பாடு ஒரு சிறிய, கணிக்கக்கூடிய ஆப்ஜெக்ட் வகைகளில் செயல்படும் பெரும்பாலான பொதுவான ஆப்ஜெக்ட்-ஓரியண்டட் மற்றும் செயல்பாட்டு வடிவங்களை உள்ளடக்கியது.
3. மெகாமார்பிசம் (மெதுவான பாதை)
மெகா = பெரிய. மார்ப் = வடிவம்.
ஒரு கால் சைட் அதிக எண்ணிக்கையிலான வெவ்வேறு ஆப்ஜெக்ட் வடிவங்களுக்கு (பல்லுருவ வரம்பை விட அதிகமாக) ஊட்டப்பட்டால், V8 ஒரு நடைமுறை முடிவை எடுக்கிறது: அது அந்த தளத்திற்கான குறிப்பிட்ட கேச்சிங்கை கைவிடுகிறது. IC ஒரு மெகாமார்பிக் நிலைக்கு மாறுகிறது.
function getID(item) {
return item.id;
}
// Imagine these objects come from a diverse, unpredictable data source.
const items = [
{ id: 1, name: 'A' },
{ id: 2, type: 'B' },
{ id: 3, value: 'C', name: 'C1'},
{ id: 4, label: 'D' },
{ id: 5, tag: 'E' },
{ id: 6, key: 'F' }
// ... many more unique shapes
];
items.forEach(getID);
இந்தச் சூழலில், `item.id` இல் உள்ள IC விரைவாக 4-5 க்கும் மேற்பட்ட வெவ்வேறு மறைக்கப்பட்ட வகுப்புகளைக் காணும். அது மெகாமார்பிக் ஆகிவிடும். இந்த நிலையில், குறிப்பிட்ட (வடிவம் -> ஆஃப்செட்) கேச்சிங் கைவிடப்படும். இன்ஜின் ஒரு பொதுவான, ஆனால் மெதுவான, ப்ராப்பர்ட்டி தேடல் முறைக்கு மாறுகிறது. இது ஒரு முற்றிலும் எளிய செயல்படுத்தலை விட மேம்படுத்தப்பட்டாலும் (அது ஒரு உலகளாவிய கேச்சை பயன்படுத்தலாம்), இது மோனோமார்பிக் அல்லது பல்லுருவ நிலைகளை விட கணிசமாக மெதுவாக இருக்கும்.
உயர்-செயல்திறன் குறியீட்டிற்கான நடைமுறை நுண்ணறிவு
இந்தக் கோட்பாட்டைப் புரிந்துகொள்வது ஒரு கல்விசார் பயிற்சி மட்டுமல்ல. இது உங்கள் பயன்பாட்டிற்கான மிகவும் மேம்படுத்தப்பட்ட குறியீட்டை உருவாக்க V8 க்கு உதவக்கூடிய நடைமுறை குறியீட்டு வழிகாட்டுதல்களாக நேரடியாக மொழிபெயர்க்கிறது.
1. மோனோமார்பிசத்திற்கு முயற்சி செய்யுங்கள்: ஆப்ஜெக்ட்களை சீராக துவக்கவும்
மிக முக்கியமான ஒரு குறிப்பு என்னவென்றால், ஒரே கட்டமைப்பைக் கொண்டிருக்க வேண்டிய ஆப்ஜெக்ட்கள் உண்மையில் ஒரே மறைக்கப்பட்ட வகுப்பைப் பகிர்ந்து கொள்கின்றன என்பதை உறுதிப்படுத்துவதாகும். இதை அடைய சிறந்த வழி அவற்றை ஒரே மாதிரியாக துவக்குவதாகும்.
மோசம்: சீரற்ற துவக்கம்
// These two objects have the same properties but different Hidden Classes.
const user1 = { name: 'Alice' };
user1.id = 1;
const user2 = { id: 2 };
user2.name = 'Bob';
// A function processing these users will see two different shapes.
function processUser(user) { /* ... */ }
நன்று: கன்ஸ்ட்ரக்டர்கள் அல்லது ஃபேக்டரிகளைப் பயன்படுத்தி சீரான துவக்கம்
class User {
constructor(id, name) {
this.id = id;
this.name = name;
}
}
const user1 = new User(1, 'Alice');
const user2 = new User(2, 'Bob');
// All User instances will have the same Hidden Class.
// Any function processing them will be monomorphic.
function processUser(user) { /* ... */ }
கன்ஸ்ட்ரக்டர்கள், ஃபேக்டரி செயல்பாடுகள் அல்லது சீராக வரிசைப்படுத்தப்பட்ட ஆப்ஜெக்ட் லிட்டரல்களைப் பயன்படுத்துவது, இந்த ஆப்ஜெக்ட்களில் செயல்படும் செயல்பாடுகளை V8 திறம்பட மேம்படுத்த முடியும் என்பதை உறுதிப்படுத்துகிறது.
2. ஸ்மார்ட் பல்லுருவத்துவத்தை ஏற்றுக்கொள்ளுங்கள்
பல்லுருவத்துவம் ஒரு தவறு அல்ல; அது நிரலாக்கத்தின் ஒரு சக்திவாய்ந்த அம்சம். சில வெவ்வேறு ஆப்ஜெக்ட் வடிவங்களில் செயல்படும் செயல்பாடுகளை வைத்திருப்பது முற்றிலும் சரியானது. உதாரணமாக, ஒரு UI நூலகத்தில், ஒரு `mountComponent` செயல்பாடு ஒரு `Button`, ஒரு `Input`, அல்லது ஒரு `Panel` ஐ ஏற்கலாம். இது பல்லுருவத்துவத்தின் ஒரு கிளாசிக், ஆரோக்கியமான பயன்பாடு ஆகும், மேலும் V8 அதை கையாள நன்கு தயாராக உள்ளது.
முக்கியமானது என்னவென்றால், பல்லுருவத்துவத்தின் அளவை குறைவாகவும் கணிக்கக்கூடியதாகவும் வைத்திருப்பது. 3 வகையான கூறுகளைக் கையாளும் ஒரு செயல்பாடு சிறந்தது. 300 ஐக் கையாளும் ஒரு செயல்பாடு மெகாமார்பிக் ஆகி மெதுவாகிவிடும்.
3. மெகாமார்பிசத்தைத் தவிர்க்கவும்: கணிக்க முடியாத வடிவங்கள் குறித்து எச்சரிக்கையாக இருங்கள்
மெகாமார்பிசம் பெரும்பாலும், ஆப்ஜெக்ட்கள் மாறுபட்ட பண்புகளுடன் திட்டமிட்ட முறையில் கட்டமைக்கப்படும் மிகவும் டைனமிக் தரவு அமைப்புகளைக் கையாளும்போது நிகழ்கிறது. உங்களுக்கு ஒரு செயல்திறன்-முக்கியமான செயல்பாடு இருந்தால், அதற்கு முற்றிலும் மாறுபட்ட வடிவங்களைக் கொண்ட ஆப்ஜெக்ட்களை அனுப்புவதைத் தவிர்க்க முயற்சிக்கவும்.
நீங்கள் அத்தகைய தரவுகளுடன் வேலை செய்ய வேண்டும் என்றால், முதலில் ஒரு இயல்பாக்குதல் (normalization) படிநிலையைக் கருத்தில் கொள்ளுங்கள். நீங்கள் கணிக்க முடியாத ஆப்ஜெக்ட்களை ஒரு சீரான, நிலையான கட்டமைப்பிற்குள் கொண்டு வந்து, பின்னர் அவற்றை உங்கள் ஹாட் லூப்பில் அனுப்பலாம்.
மோசம்: ஹாட் பாதையில் மெகாமார்பிக் அணுகல்
function calculateTotal(items) {
let total = 0;
for (const item of items) {
// This will become megamorphic if `items` contains dozens of shapes.
total += item.price;
}
return total;
}
சிறந்தது: முதலில் தரவை இயல்பாக்குங்கள்
function calculateTotal(rawItems) {
const normalizedItems = rawItems.map(item => ({
// Create a consistent shape
price: item.price || item.cost || item.value || 0
}));
let total = 0;
for (const item of normalizedItems) {
// This access will be monomorphic!
total += item.price;
}
return total;
}
4. உருவாக்கப்பட்ட பிறகு வடிவங்களை மாற்ற வேண்டாம் (குறிப்பாக `delete` உடன்)
ஒரு ஆப்ஜெக்ட் உருவாக்கப்பட்ட பிறகு அதிலிருந்து பண்புகளைச் சேர்ப்பது அல்லது நீக்குவது ஒரு மறைக்கப்பட்ட வகுப்பு மாற்றத்தை கட்டாயப்படுத்துகிறது. ஒரு ஹாட் செயல்பாட்டிற்குள் இதைச் செய்வது மேம்படுத்தல் கருவியை குழப்பக்கூடும். `delete` என்ற முக்கிய சொல் குறிப்பாக சிக்கலானது, ஏனெனில் அது V8 ஐ ஆப்ஜெக்ட்டின் பின்னிணைப்பு சேமிப்பகத்தை ஒரு மெதுவான 'அகராதி பயன்முறைக்கு' மாற்ற கட்டாயப்படுத்தலாம், இது அந்த ஆப்ஜெக்ட்டிற்கான அனைத்து மறைக்கப்பட்ட வகுப்பு மேம்படுத்தல்களையும் செல்லாததாக்குகிறது.
நீங்கள் ஒரு ப்ராப்பர்ட்டியை 'நீக்க' வேண்டும் என்றால், `delete` ஐப் பயன்படுத்துவதற்குப் பதிலாக அதன் மதிப்பை `null` அல்லது `undefined` ஆக அமைப்பது செயல்திறனுக்கு எப்போதும் சிறந்தது.
முடிவுரை: இன்ஜினுடன் கைகோர்த்து
V8 ஜாவாஸ்கிரிப்ட் இன்ஜின் நவீன தொகுப்பு தொழில்நுட்பத்தின் ஒரு அதிசயம். ஒரு டைனமிக், நெகிழ்வான மொழியை எடுத்து, அதை கிட்டத்தட்ட நேட்டிவ் வேகத்தில் செயல்படுத்தும் அதன் திறன் இன்லைன் கேச்சிங் போன்ற மேம்படுத்தல்களுக்கு ஒரு சான்றாகும். ஒரு ப்ராப்பர்ட்டி அணுகலின் பயணத்தைப் புரிந்துகொள்வதன் மூலம்—துவக்கப்படாத நிலையில் இருந்து மிகவும் மேம்படுத்தப்பட்ட மோனோமார்பிக் நிலைக்கு, நடைமுறை பல்லுருவ நிலை வழியாக, மற்றும் இறுதியாக மெதுவான மெகாமார்பிக் பின்னிணைப்புக்கு—நாம் டெவலப்பர்களாக இன்ஜினுக்கு எதிராக இல்லாமல், அதனுடன் சேர்ந்து செயல்படும் குறியீட்டை எழுத முடியும்.
குறியீட்டின் ஒவ்வொரு வரியிலும் இந்த மைக்ரோ-மேம்படுத்தல்களைப் பற்றி நீங்கள் சிந்தித்துக் கொண்டிருக்க தேவையில்லை. ஆனால் உங்கள் பயன்பாட்டின் செயல்திறன்-முக்கியமான பாதைகளுக்கு—வினாடிக்கு ஆயிரக்கணக்கான முறை இயங்கும் குறியீட்டிற்கு—இந்தக் கொள்கைகள் மிக முக்கியமானவை. சீரான ஆப்ஜெக்ட் துவக்கத்தின் மூலம் மோனோமார்பிசத்தை ஊக்குவிப்பதன் மூலமும், நீங்கள் அறிமுகப்படுத்தும் பல்லுருவத்துவத்தின் அளவை கவனத்தில் கொள்வதன் மூலமும், V8 JIT கம்பைலருக்கு அதன் முழு மேம்படுத்தல் சக்தியை வெளிப்படுத்த தேவையான நிலையான, கணிக்கக்கூடிய வடிவங்களை நீங்கள் வழங்க முடியும். இதன் விளைவாக, உலகெங்கிலும் உள்ள பயனர்களுக்கு சிறந்த அனுபவத்தை வழங்கும் வேகமான, திறமையான பயன்பாடுகள் கிடைக்கும்.