மல்டி-த்ரெடட் அல்லது ஒத்திசைவற்ற சூழல்களில் செயல்திறனை மேம்படுத்த, இணை தரவு கட்டமைப்பு செயல்பாடுகளுக்கான ஜாவாஸ்கிரிப்டில் ஒரு கன்கரென்ட் மேப் என்ற கருத்தை ஆராயுங்கள். அதன் நன்மைகள், செயல்படுத்தும் சவால்கள் மற்றும் நடைமுறை பயன்பாட்டு நிகழ்வுகளைக் கற்றுக்கொள்ளுங்கள்.
ஜாவாஸ்கிரிப்ட் கன்கரென்ட் மேப்: மேம்பட்ட செயல்திறனுக்காக இணை தரவு கட்டமைப்பு செயல்பாடுகள்
நவீன ஜாவாஸ்கிரிப்ட் மேம்பாட்டில், குறிப்பாக Node.js சூழல்கள் மற்றும் வெப் வொர்க்கர்களைப் பயன்படுத்தும் வலை உலாவிகளில், ஒருங்கமைந்த செயல்பாடுகளைச் செய்யும் திறன் மிகவும் முக்கியத்துவம் பெறுகிறது. தரவு கட்டமைப்பு கையாளுதலில் ஒருங்கமைவு செயல்திறனை கணிசமாக பாதிக்கும் ஒரு பகுதியாகும். இந்த வலைப்பதிவு இடுகை ஜாவாஸ்கிரிப்டில் ஒரு கன்கரென்ட் மேப் என்ற கருத்தை ஆராய்கிறது, இது பயன்பாட்டின் செயல்திறனை வியத்தகு முறையில் மேம்படுத்தும் இணை தரவு கட்டமைப்பு செயல்பாடுகளுக்கான ஒரு சக்திவாய்ந்த கருவியாகும்.
ஒருங்கமைந்த தரவு கட்டமைப்புகளின் தேவையைப் புரிந்துகொள்ளுதல்
உள்ளமைக்கப்பட்ட Map மற்றும் Object போன்ற பாரம்பரிய ஜாவாஸ்கிரிப்ட் தரவு கட்டமைப்புகள் இயல்பாகவே ஒற்றை-த்ரெடட் கொண்டவை. இதன் பொருள், எந்த நேரத்திலும் ஒரு செயல்பாடு மட்டுமே தரவு கட்டமைப்பை அணுகவோ அல்லது மாற்றவோ முடியும். இது நிரல் நடத்தையைப் பற்றி பகுத்தறிவதை எளிதாக்கினாலும், பின்வரும் சூழ்நிலைகளில் இது ஒரு இடையூறாக மாறும்:
- மல்டி-த்ரெடட் சூழல்கள்: ஜாவாஸ்கிரிப்ட் குறியீட்டை இணை த்ரெட்களில் இயக்க வெப் வொர்க்கர்களைப் பயன்படுத்தும்போது, பல வொர்க்கர்களிடமிருந்து பகிரப்பட்ட
Map-ஐ ஒரே நேரத்தில் அணுகுவது ரேஸ் கண்டிஷன்கள் மற்றும் தரவு சிதைவுக்கு வழிவகுக்கும். - ஒத்திசைவற்ற செயல்பாடுகள்: Node.js அல்லது உலாவி அடிப்படையிலான பயன்பாடுகளில் எண்ணற்ற ஒத்திசைவற்ற பணிகளைக் (எ.கா., நெட்வொர்க் கோரிக்கைகள், கோப்பு I/O) கையாளும்போது, பல கால்பேக்குகள் ஒரு
Map-ஐ ஒரே நேரத்தில் மாற்ற முயற்சி செய்யலாம், இதன் விளைவாக கணிக்க முடியாத நடத்தை ஏற்படும். - உயர் செயல்திறன் பயன்பாடுகள்: நிகழ்நேர தரவு பகுப்பாய்வு, கேம் மேம்பாடு அல்லது அறிவியல் உருவகப்படுத்துதல்கள் போன்ற தீவிர தரவு செயலாக்கத் தேவைகளைக் கொண்ட பயன்பாடுகள், ஒருங்கமைந்த தரவு கட்டமைப்புகளால் வழங்கப்படும் இணைத்தன்மையிலிருந்து பயனடையலாம்.
ஒரு கன்கரென்ட் மேப், பல த்ரெட்கள் அல்லது ஒத்திசைவற்ற சூழல்களில் இருந்து வரைபடத்தின் உள்ளடக்கங்களை ஒரே நேரத்தில் பாதுகாப்பாக அணுகவும் மாற்றவும் வழிமுறைகளை வழங்குவதன் மூலம் இந்த சவால்களை எதிர்கொள்கிறது. இது செயல்பாடுகளை இணையாக செயல்படுத்த அனுமதிக்கிறது, இது சில சூழ்நிலைகளில் குறிப்பிடத்தக்க செயல்திறன் ஆதாயங்களுக்கு வழிவகுக்கிறது.
கன்கரென்ட் மேப் என்றால் என்ன?
ஒரு கன்கரென்ட் மேப் என்பது தரவு சிதைவு அல்லது ரேஸ் கண்டிஷன்களை ஏற்படுத்தாமல், பல த்ரெட்கள் அல்லது ஒத்திசைவற்ற செயல்பாடுகள் அதன் உள்ளடக்கங்களை ஒரே நேரத்தில் அணுகவும் மாற்றவும் அனுமதிக்கும் ஒரு தரவு கட்டமைப்பாகும். இது பொதுவாக இவற்றின் பயன்பாட்டின் மூலம் அடையப்படுகிறது:
- அட்டாமிக் செயல்பாடுகள்: செயல்பாட்டின் போது வேறு எந்த த்ரெட்டும் தலையிட முடியாது என்பதை உறுதி செய்யும், ஒற்றை, பிரிக்க முடியாத அலகாக செயல்படும் செயல்பாடுகள்.
- பூட்டுதல் வழிமுறைகள்: மியூட்டெக்ஸ்கள் அல்லது செமாஃபோர்கள் போன்ற நுட்பங்கள், ஒரே நேரத்தில் ஒரு த்ரெட் மட்டுமே தரவு கட்டமைப்பின் ஒரு குறிப்பிட்ட பகுதியை அணுக அனுமதித்து, ஒருங்கமைந்த மாற்றங்களைத் தடுக்கின்றன.
- லாக்-ஃப்ரீ தரவு கட்டமைப்புகள்: வெளிப்படையான பூட்டுதலைத் தவிர்த்து, தரவு நிலைத்தன்மையை உறுதிப்படுத்த அட்டாமிக் செயல்பாடுகள் மற்றும் புத்திசாலித்தனமான வழிமுறைகளைப் பயன்படுத்தும் மேம்பட்ட தரவு கட்டமைப்புகள்.
ஒரு கன்கரென்ட் மேப்பின் குறிப்பிட்ட செயல்படுத்தல் விவரங்கள் நிரலாக்க மொழி மற்றும் அடிப்படைக் கணினி கட்டமைப்பைப் பொறுத்து மாறுபடும். ஜாவாஸ்கிரிப்டில், மொழியின் ஒற்றை-த்ரெடட் தன்மை காரணமாக உண்மையான ஒருங்கமைந்த தரவு கட்டமைப்பை செயல்படுத்துவது சவாலானது. இருப்பினும், வெப் வொர்க்கர்கள் மற்றும் ஒத்திசைவற்ற செயல்பாடுகள் போன்ற நுட்பங்களையும், பொருத்தமான ஒத்திசைவு வழிமுறைகளையும் பயன்படுத்தி நாம் ஒருங்கமைவை உருவகப்படுத்தலாம்.
வெப் வொர்க்கர்களுடன் ஜாவாஸ்கிரிப்டில் ஒருங்கமைவை உருவகப்படுத்துதல்
வெப் வொர்க்கர்கள் தனித்தனி த்ரெட்களில் ஜாவாஸ்கிரிப்ட் குறியீட்டை இயக்க ஒரு வழியை வழங்குகின்றன, இது ஒரு உலாவி சூழலில் ஒருங்கமைவை உருவகப்படுத்த அனுமதிக்கிறது. ஒரு Map-ல் சேமிக்கப்பட்ட ஒரு பெரிய தரவுத்தொகுப்பில் சில கணக்கீட்டு ரீதியாக தீவிரமான செயல்பாடுகளைச் செய்ய விரும்பும் ஒரு எடுத்துக்காட்டைக் கருத்தில் கொள்வோம்.
எடுத்துக்காட்டு: வெப் வொர்க்கர்கள் மற்றும் ஒரு பகிரப்பட்ட மேப் உடன் இணை தரவு செயலாக்கம்
நம்மிடம் பயனர் தரவைக் கொண்ட ஒரு Map உள்ளது என்றும், ஒவ்வொரு நாட்டிலும் உள்ள பயனர்களின் சராசரி வயதைக் கணக்கிட விரும்புகிறோம் என்றும் வைத்துக்கொள்வோம். நாம் தரவை பல வெப் வொர்க்கர்களிடையே பிரித்து, ஒவ்வொரு வொர்க்கரையும் தரவின் ஒரு துணைக்குழுவை ஒரே நேரத்தில் செயலாக்க வைக்கலாம்.
முக்கிய த்ரெட் (index.html அல்லது main.js):
// Create a large Map of user data
const userData = new Map();
for (let i = 0; i < 10000; i++) {
const country = ['USA', 'Canada', 'UK', 'Germany', 'France'][i % 5];
userData.set(i, { age: Math.floor(Math.random() * 60) + 18, country });
}
// Divide the data into chunks for each worker
const numWorkers = 4;
const chunkSize = Math.ceil(userData.size / numWorkers);
const dataChunks = [];
let i = 0;
for (let j = 0; j < numWorkers; j++) {
const chunk = new Map();
let count = 0;
for (; i < userData.size && count < chunkSize; i++) {
chunk.set(i, userData.get(i));
count++;
}
dataChunks.push(chunk);
}
// Create Web Workers
const workers = [];
const results = new Map();
let completedWorkers = 0;
for (let i = 0; i < numWorkers; i++) {
const worker = new Worker('worker.js');
workers.push(worker);
worker.onmessage = (event) => {
const { countryAverages } = event.data;
// Merge results from the worker
for (const [country, average] of countryAverages) {
if (results.has(country)) {
const existing = results.get(country);
results.set(country, { sum: existing.sum + average.sum, count: existing.count + average.count });
} else {
results.set(country, average);
}
}
completedWorkers++;
if (completedWorkers === numWorkers) {
// All workers have finished
const finalAverages = new Map();
for (const [country, data] of results) {
finalAverages.set(country, data.sum / data.count);
}
console.log('Final Averages:', finalAverages);
}
worker.terminate(); // Terminate the worker after use
};
worker.onerror = (error) => {
console.error('Worker error:', error);
};
// Send data chunk to the worker
worker.postMessage({ data: Array.from(dataChunks[i]) });
}
வெப் வொர்க்கர் (worker.js):
self.onmessage = (event) => {
const { data } = event.data;
const userData = new Map(data);
const countryAverages = new Map();
for (const [id, user] of userData) {
const { country, age } = user;
if (countryAverages.has(country)) {
const existing = countryAverages.get(country);
countryAverages.set(country, { sum: existing.sum + age, count: existing.count + 1 });
} else {
countryAverages.set(country, { sum: age, count: 1 });
}
}
self.postMessage({ countryAverages: countryAverages });
};
இந்த எடுத்துக்காட்டில், ஒவ்வொரு வெப் வொர்க்கரும் அதன் சொந்த சுயாதீனமான தரவு நகலைச் செயலாக்குகிறது. இது வெளிப்படையான பூட்டுதல் அல்லது ஒத்திசைவு வழிமுறைகளின் தேவையைத் தவிர்க்கிறது. இருப்பினும், வொர்க்கர்களின் எண்ணிக்கை அல்லது ஒன்றிணைப்பு செயல்பாட்டின் சிக்கலான தன்மை அதிகமாக இருந்தால், முக்கிய த்ரெட்டில் முடிவுகளை ஒன்றிணைப்பது ஒரு இடையூறாக மாறும். இந்த நிலையில், நீங்கள் இதுபோன்ற நுட்பங்களைப் பயன்படுத்தலாம்:
- அட்டாமிக் புதுப்பிப்புகள்: ஒருங்கிணைப்பு செயல்பாட்டை அட்டாமிக் முறையில் செய்ய முடிந்தால், SharedArrayBuffer மற்றும் Atomics செயல்பாடுகளைப் பயன்படுத்தி வொர்க்கர்களிடமிருந்து நேரடியாக ஒரு பகிரப்பட்ட தரவு கட்டமைப்பைப் புதுப்பிக்கலாம். இருப்பினும், இந்த அணுகுமுறைக்கு கவனமான ஒத்திசைவு தேவைப்படுகிறது மற்றும் சரியாக செயல்படுத்துவது சிக்கலானதாக இருக்கலாம்.
- செய்தி அனுப்புதல்: முக்கிய த்ரெட்டில் முடிவுகளை ஒன்றிணைப்பதற்குப் பதிலாக, வொர்க்கர்கள் ஒருவருக்கொருவர் பகுதி முடிவுகளை அனுப்பலாம், இது ஒன்றிணைக்கும் பணிச்சுமையை பல த்ரெட்களில் விநியோகிக்கிறது.
ஒத்திசைவற்ற செயல்பாடுகள் மற்றும் பூட்டுகளுடன் ஒரு அடிப்படை கன்கரென்ட் மேப்பை செயல்படுத்துதல்
வெப் வொர்க்கர்கள் உண்மையான இணைத்தன்மையை வழங்கும்போது, ஒரு ஒற்றை த்ரெட்டில் ஒத்திசைவற்ற செயல்பாடுகள் மற்றும் பூட்டுதல் வழிமுறைகளைப் பயன்படுத்தி ஒருங்கமைவை உருவகப்படுத்தலாம். இந்த அணுகுமுறை குறிப்பாக I/O-சார்ந்த செயல்பாடுகள் பொதுவான Node.js சூழல்களில் பயனுள்ளதாக இருக்கும்.
ஒரு எளிய பூட்டுதல் வழிமுறையைப் பயன்படுத்தி செயல்படுத்தப்பட்ட ஒரு கன்கரென்ட் மேப்பின் அடிப்படை எடுத்துக்காட்டு இங்கே:
class ConcurrentMap {
constructor() {
this.map = new Map();
this.lock = false; // Simple lock using a boolean flag
}
async get(key) {
while (this.lock) {
// Wait for the lock to be released
await new Promise((resolve) => setTimeout(resolve, 0));
}
return this.map.get(key);
}
async set(key, value) {
while (this.lock) {
// Wait for the lock to be released
await new Promise((resolve) => setTimeout(resolve, 0));
}
this.lock = true; // Acquire the lock
try {
this.map.set(key, value);
} finally {
this.lock = false; // Release the lock
}
}
async delete(key) {
while (this.lock) {
// Wait for the lock to be released
await new Promise((resolve) => setTimeout(resolve, 0));
}
this.lock = true; // Acquire the lock
try {
this.map.delete(key);
} finally {
this.lock = false; // Release the lock
}
}
}
// Example Usage
async function example() {
const concurrentMap = new ConcurrentMap();
// Simulate concurrent access
const promises = [];
for (let i = 0; i < 10; i++) {
promises.push(
(async () => {
await concurrentMap.set(i, `Value ${i}`);
console.log(`Set ${i}:`, await concurrentMap.get(i));
await concurrentMap.delete(i);
console.log(`Deleted ${i}:`, await concurrentMap.get(i));
})()
);
}
await Promise.all(promises);
console.log('Finished!');
}
example();
இந்த எடுத்துக்காட்டு ஒரு எளிய பூலியன் கொடியை பூட்டாகப் பயன்படுத்துகிறது. Map-ஐ அணுகுவதற்கு அல்லது மாற்றுவதற்கு முன், ஒவ்வொரு ஒத்திசைவற்ற செயல்பாடும் பூட்டு வெளியிடப்படும் வரை காத்திருந்து, பூட்டைப் பெற்று, செயல்பாட்டைச் செய்து, பின்னர் பூட்டை வெளியிடுகிறது. இது ஒரே நேரத்தில் ஒரு செயல்பாடு மட்டுமே Map-ஐ அணுக முடியும் என்பதை உறுதி செய்கிறது, ரேஸ் கண்டிஷன்களைத் தடுக்கிறது.
முக்கிய குறிப்பு: இது மிகவும் அடிப்படையான எடுத்துக்காட்டு மற்றும் உற்பத்தி சூழல்களில் பயன்படுத்தப்படக்கூடாது. இது மிகவும் திறனற்றது மற்றும் முட்டுக்கட்டை போன்ற சிக்கல்களுக்கு ஆளாகக்கூடியது. நிஜ உலகப் பயன்பாடுகளில் செமாஃபோர்கள் அல்லது மியூட்டெக்ஸ்கள் போன்ற வலுவான பூட்டுதல் வழிமுறைகளைப் பயன்படுத்த வேண்டும்.
சவால்கள் மற்றும் கருத்தில் கொள்ள வேண்டியவை
ஜாவாஸ்கிரிப்டில் ஒரு கன்கரென்ட் மேப்பை செயல்படுத்துவது பல சவால்களை முன்வைக்கிறது:
- ஜாவாஸ்கிரிப்டின் ஒற்றை-த்ரெடட் தன்மை: ஜாவாஸ்கிரிப்ட் அடிப்படையில் ஒற்றை-த்ரெடட் கொண்டது, இது அடையக்கூடிய உண்மையான இணைத்தன்மையின் அளவைக் கட்டுப்படுத்துகிறது. வெப் வொர்க்கர்கள் இந்த வரம்பைத் தவிர்க்க ஒரு வழியை வழங்குகின்றன, ஆனால் அவை கூடுதல் சிக்கலை அறிமுகப்படுத்துகின்றன.
- ஒத்திசைவு மேல்நிலைச் செலவு: பூட்டுதல் வழிமுறைகள் மேல்நிலைச் செலவை அறிமுகப்படுத்துகின்றன, இது கவனமாக செயல்படுத்தப்படாவிட்டால், ஒருங்கமைவின் செயல்திறன் நன்மைகளை ரத்து செய்யலாம்.
- சிக்கலான தன்மை: ஒருங்கமைந்த தரவு கட்டமைப்புகளை வடிவமைத்து செயல்படுத்துவது இயல்பாகவே சிக்கலானது மற்றும் ஒருங்கமைவு கருத்துகள் மற்றும் சாத்தியமான ஆபத்துகள் பற்றிய ஆழமான புரிதல் தேவை.
- பிழைத்திருத்தம்: ஒருங்கமைந்த குறியீட்டை பிழைத்திருத்தம் செய்வது, ஒருங்கமைந்த செயல்பாட்டின் தீர்மானிக்கப்படாத தன்மை காரணமாக ஒற்றை-த்ரெடட் குறியீட்டை பிழைத்திருத்தம் செய்வதை விட கணிசமாக சவாலானதாக இருக்கும்.
ஜாவாஸ்கிரிப்டில் கன்கரென்ட் மேப்களின் பயன்பாட்டு நிகழ்வுகள்
சவால்கள் இருந்தபோதிலும், கன்கரென்ட் மேப்கள் பல சூழ்நிலைகளில் மதிப்புமிக்கவையாக இருக்கும்:
- தற்காலிக சேமிப்பு (Caching): பல த்ரெட்கள் அல்லது ஒத்திசைவற்ற சூழல்களில் இருந்து அணுகக்கூடிய மற்றும் புதுப்பிக்கக்கூடிய ஒரு ஒருங்கமைந்த தற்காலிக சேமிப்பை செயல்படுத்துதல்.
- தரவு திரட்டல்: நிகழ்நேர தரவு பகுப்பாய்வு பயன்பாடுகளில் போன்ற, பல மூலங்களிலிருந்து தரவை ஒரே நேரத்தில் திரட்டுதல்.
- பணி வரிசைகள் (Task Queues): பல வொர்க்கர்களால் ஒரே நேரத்தில் செயலாக்கக்கூடிய ஒரு பணி வரிசையை நிர்வகித்தல்.
- கேம் மேம்பாடு: மல்டிபிளேயர் கேம்களில் கேம் நிலையை ஒரே நேரத்தில் நிர்வகித்தல்.
கன்கரென்ட் மேப்களுக்கான மாற்று வழிகள்
ஒரு கன்கரென்ட் மேப்பை செயல்படுத்துவதற்கு முன், மாற்று அணுகுமுறைகள் மிகவும் பொருத்தமானதாக இருக்குமா என்பதைக் கருத்தில் கொள்ளுங்கள்:
- மாறாத தரவு கட்டமைப்புகள்: மாறாத தரவு கட்டமைப்புகள், தரவு உருவாக்கப்பட்ட பிறகு மாற்றப்பட முடியாது என்பதை உறுதி செய்வதன் மூலம் பூட்டுதலின் தேவையை நீக்கலாம். Immutable.js போன்ற நூலகங்கள் ஜாவாஸ்கிரிப்ட்டிற்கு மாறாத தரவு கட்டமைப்புகளை வழங்குகின்றன.
- செய்தி அனுப்புதல்: த்ரெட்கள் அல்லது ஒத்திசைவற்ற சூழல்களுக்கு இடையில் தொடர்பு கொள்ள செய்தி அனுப்புதலைப் பயன்படுத்துவது பகிரப்பட்ட மாற்றக்கூடிய நிலையின் தேவையை முற்றிலும் தவிர்க்கலாம்.
- கணக்கீட்டை வெளியேற்றுதல்: கணக்கீட்டு ரீதியாக தீவிரமான பணிகளை பின்தள சேவைகள் அல்லது கிளவுட் செயல்பாடுகளுக்கு வெளியேற்றுவது முக்கிய த்ரெட்டை விடுவித்து, பயன்பாட்டின் பதிலளிப்புத் திறனை மேம்படுத்தலாம்.
முடிவுரை
கன்கரென்ட் மேப்கள் ஜாவாஸ்கிரிப்டில் இணை தரவு கட்டமைப்பு செயல்பாடுகளுக்கு ஒரு சக்திவாய்ந்த கருவியை வழங்குகின்றன. ஜாவாஸ்கிரிப்டின் ஒற்றை-த்ரெடட் தன்மை மற்றும் ஒருங்கமைவின் சிக்கலான தன்மை காரணமாக அவற்றை செயல்படுத்துவது சவால்களை முன்வைத்தாலும், அவை மல்டி-த்ரெடட் அல்லது ஒத்திசைவற்ற சூழல்களில் செயல்திறனை கணிசமாக மேம்படுத்த முடியும். வர்த்தகப் பரிமாற்றங்களைப் புரிந்துகொண்டு மாற்று அணுகுமுறைகளை கவனமாகக் கருத்தில் கொள்வதன் மூலம், டெவலப்பர்கள் கன்கரென்ட் மேப்களைப் பயன்படுத்தி திறமையான மற்றும் அளவிடக்கூடிய ஜாவாஸ்கிரிப்ட் பயன்பாடுகளை உருவாக்க முடியும்.
உங்கள் ஒருங்கமைந்த குறியீடு சரியாக செயல்படுவதையும், செயல்திறன் நன்மைகள் ஒத்திசைவின் மேல்நிலைச் செலவை விட அதிகமாக இருப்பதையும் உறுதிசெய்ய, அதை முழுமையாக சோதித்து செயல்திறன் அளவீடு செய்ய நினைவில் கொள்ளுங்கள்.
மேலும் ஆராய
- Web Workers API: MDN Web Docs
- SharedArrayBuffer and Atomics: MDN Web Docs
- Immutable.js: அதிகாரப்பூர்வ வலைத்தளம்