ব্রুফার উত্তরটি বেশ চতুর, প্রকৃতপক্ষে - চিত্তাকর্ষকভাবে চতুর, সত্যই ... rfc4122 অনুগত, কিছুটা পঠনযোগ্য এবং কমপ্যাক্ট। অসাধারণ!
তবে আপনি যদি সেই নিয়মিত অভিব্যক্তিটি দেখছেন, সেই বহু replace()
কলব্যাকগুলি toString()
এবং Math.random()
ফাংশন কলগুলি (যেখানে তিনি কেবল ফলাফলের 4 টি বিট ব্যবহার করছেন এবং বাকী অংশটি নষ্ট করছেন), আপনি অভিনয় সম্পর্কে অবাক হতে শুরু করতে পারেন। প্রকৃতপক্ষে, জেলপেট এমনকি জেনেরিক জিইউডি গতির জন্য আরএফসি টস আউট করার সিদ্ধান্ত নিয়েছে generateQuickGUID
।
তবে, আমরা কি গতি এবং আরএফসি সম্মতি পেতে পারি ? আমি বলতে হ্যাঁ! আমরা কি পঠনযোগ্যতা বজায় রাখতে পারি? ভাল ... আসলে নয়, তবে আপনি যদি অনুসরণ করে যান তবে এটি সহজ।
তবে প্রথমে আমার ফলাফলগুলি ব্রুফার তুলনায় guid
(স্বীকৃত উত্তর) এবং অ আরএফসি-অনুগত generateQuickGuid
:
Desktop Android
broofa: 1617ms 12869ms
e1: 636ms 5778ms
e2: 606ms 4754ms
e3: 364ms 3003ms
e4: 329ms 2015ms
e5: 147ms 1156ms
e6: 146ms 1035ms
e7: 105ms 726ms
guid: 962ms 10762ms
generateQuickGuid: 292ms 2961ms
- Note: 500k iterations, results will vary by browser/cpu.
সুতরাং অপ্টিমাইজেশন আমার 6 ষ্ঠ পুনরাবৃত্তির কসম, আমি বেশি জনপ্রিয় উত্তর বীট 12X , ওভার দ্বারা গৃহীত উত্তর 9x , এবং দ্রুত অ অনুবর্তী উত্তর 2-3X । এবং আমি এখনও rfc4122 অনুগত।
কিভাবে আগ্রহী? আমি পূর্ণ উৎস রেখেছি http://jsfiddle.net/jcward/7hyaC/3/ এবং এর http://jsperf.com/uuid-generator-opt/4
একটি ব্যাখ্যার জন্য, ব্রুফার কোড দিয়ে শুরু করা যাক:
function broofa() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
}
console.log(broofa())
সুতরাং এটি x
কোনও র্যান্ডম হেক্স ডিজিটের y
সাথে, এলোমেলো উপাত্তের সাথে প্রতিস্থাপন করে (শীর্ষে দুটি বিটকে 10
আরএফসি স্পেস অনুসারে জোর করা ব্যতীত ), এবং রেজেক্সটি অক্ষর -
বা 4
চরিত্রগুলির সাথে মেলে না , তাই তাকে মোকাবেলা করতে হবে না। খুব, খুব চতুর।
প্রথমটি জানতে হবে যে ফাংশন কলগুলি ব্যয়বহুল, যেমনটি নিয়মিত এক্সপ্রেশন হয় (যদিও তিনি কেবল 1 ব্যবহার করেন, এটিতে 32 টি কলব্যাক রয়েছে, প্রতিটি ম্যাচের জন্য একটি করে, এবং 32 টি কলব্যাকের প্রত্যেকটিতে এটি ম্যাথ.র্যান্ডম () এবং ভি কল করে। toString (16))।
পারফরম্যান্সের দিকে প্রথম পদক্ষেপটি হ'ল RegEx এবং এর কলব্যাক ফাংশনগুলি মুছে ফেলা এবং পরিবর্তে একটি সাধারণ লুপ ব্যবহার করা। এর অর্থ আমাদের ব্রোফা যেখানে করেনি সেখানে -
এবং 4
চরিত্রগুলি নিয়ে কাজ করতে হবে। এছাড়াও, নোট করুন যে আমরা তার স্ট্রিং স্ট্রিং টেম্পলেট আর্কিটেকচারটি রাখতে স্ট্রিং অ্যারে সূচক ব্যবহার করতে পারি:
function e1() {
var u='',i=0;
while(i++<36) {
var c='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'[i-1],r=Math.random()*16|0,v=c=='x'?r:(r&0x3|0x8);
u+=(c=='-'||c=='4')?c:v.toString(16)
}
return u;
}
console.log(e1())
মূলত, একই অভ্যন্তর যুক্তি, যা আমরা পরীক্ষা করি -
বা না রেখে 4
এবং কিছুক্ষণ লুপ ব্যবহার করি ( replace()
কলব্যাকের পরিবর্তে ) আমাদের প্রায় 3 এক্স উন্নতি দেয়!
পরবর্তী পদক্ষেপটি ডেস্কটপে ছোট একটি তবে মোবাইলে একটি শালীন পার্থক্য তৈরি করে। আসুন কম ম্যাথ.আরন্ডম () কল করি এবং সেই সমস্ত র্যান্ডম বিটগুলি ব্যবহার করে এর মধ্যে ৮ 87% দূরে একটি এলোমেলো বাফার দিয়ে ফেলে রাখি যা প্রতিটি পুনরাবৃত্তির স্থানান্তরিত হয়। আসুন সেই টেমপ্লেট সংজ্ঞাটি লুপের বাইরেও সরিয়ে দিন, কেবল যদি এটি সহায়তা করে:
function e2() {
var u='',m='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx',i=0,rb=Math.random()*0xffffffff|0;
while(i++<36) {
var c=m[i-1],r=rb&0xf,v=c=='x'?r:(r&0x3|0x8);
u+=(c=='-'||c=='4')?c:v.toString(16);rb=i%8==0?Math.random()*0xffffffff|0:rb>>4
}
return u
}
console.log(e2())
এটি আমাদের প্ল্যাটফর্মের উপর নির্ভর করে 10-30% বাঁচায়। খারাপ না. তবে পরবর্তী বড় পদক্ষেপটি একটি অপ্টিমাইজেশন ক্লাসিক - চেহারা আপ টেবিলের সাথে পুরোপুরি টস্ট্রিং ফাংশন কলগুলি থেকে মুক্তি পাবে। একটি সাধারণ 16-উপাদান অনুসন্ধানের টেবিলটি খুব কম সময়ে টু স্ট্রিংয়ের কাজ সম্পাদন করবে (16):
function e3() {
var h='0123456789abcdef';
var k='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
/* same as e4() below */
}
function e4() {
var h=['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
var k=['x','x','x','x','x','x','x','x','-','x','x','x','x','-','4','x','x','x','-','y','x','x','x','-','x','x','x','x','x','x','x','x','x','x','x','x'];
var u='',i=0,rb=Math.random()*0xffffffff|0;
while(i++<36) {
var c=k[i-1],r=rb&0xf,v=c=='x'?r:(r&0x3|0x8);
u+=(c=='-'||c=='4')?c:h[v];rb=i%8==0?Math.random()*0xffffffff|0:rb>>4
}
return u
}
console.log(e4())
পরের অপটিমাইজেশনটি আরও একটি ক্লাসিক। যেহেতু আমরা প্রতিটি লুপের পুনরাবৃত্তিতে কেবল 4-বিট আউটপুট পরিচালনা করছি, আসুন লুপের সংখ্যাটি অর্ধেক কেটে প্রতিটি বিবর্তন 8-বিট প্রক্রিয়া করি। এটি তাত্ক্ষণিক যেহেতু আমাদের এখনও আরএফসি অনুগত বিট অবস্থানগুলি পরিচালনা করতে হবে তবে এটি খুব বেশি কঠিন নয়। তারপরে 0x00 - 0xff সঞ্চয় করতে আমাদের একটি বৃহত্তর সন্ধানের টেবিল তৈরি করতে হবে (16x16, বা 256) এবং আমরা ই 5 () ফাংশনের বাইরে কেবল একবার এটি তৈরি করব।
var lut = []; for (var i=0; i<256; i++) { lut[i] = (i<16?'0':'')+(i).toString(16); }
function e5() {
var k=['x','x','x','x','-','x','x','-','4','x','-','y','x','-','x','x','x','x','x','x'];
var u='',i=0,rb=Math.random()*0xffffffff|0;
while(i++<20) {
var c=k[i-1],r=rb&0xff,v=c=='x'?r:(c=='y'?(r&0x3f|0x80):(r&0xf|0x40));
u+=(c=='-')?c:lut[v];rb=i%4==0?Math.random()*0xffffffff|0:rb>>8
}
return u
}
console.log(e5())
আমি একটি E6 () চেষ্টা করেছি যা একবারে 16-বিট প্রসেস করে, এখনও 256-উপাদান LUT ব্যবহার করে এবং এটি অপ্টিমাইজেশনের হ্রাসকারী রিটার্ন দেখায়। যদিও এটির পুনরাবৃত্তি কম ছিল, অভ্যন্তরীণ যুক্তি বর্ধিত প্রক্রিয়াজাতকরণ দ্বারা জটিল হয়েছিল এবং এটি ডেস্কটপে এটি সম্পাদন করেছিল এবং মোবাইলে মাত্র 10% দ্রুত faster
চূড়ান্ত অপ্টিমাইজেশন কৌশল প্রয়োগ করতে - লুপটি আনরোল করুন। যেহেতু আমরা একটি নির্দিষ্ট সংখ্যক বার লুপ করছি, আমরা প্রযুক্তিগতভাবে এগুলি হাতে হাতে লিখে রাখতে পারি। আমি একবারে চেষ্টা করেছি এমন একক র্যান্ডম ভেরিয়েবল আর দিয়ে যা আমি পুনরায় বরাদ্দ রেখেছি, এবং পারফরম্যান্সটি ট্যাঙ্ক করেছি। তবে সামনে চারটি ভেরিয়েবল নির্ধারিত এলোমেলো ডেটা, তারপরে অনুসন্ধান সারণীটি ব্যবহার করে এবং যথাযথ আরএফসি বিট প্রয়োগ করার সাথে, এই সংস্করণটি তাদের সমস্ত ধূমপান করে:
var lut = []; for (var i=0; i<256; i++) { lut[i] = (i<16?'0':'')+(i).toString(16); }
function e7()
{
var d0 = Math.random()*0xffffffff|0;
var d1 = Math.random()*0xffffffff|0;
var d2 = Math.random()*0xffffffff|0;
var d3 = Math.random()*0xffffffff|0;
return lut[d0&0xff]+lut[d0>>8&0xff]+lut[d0>>16&0xff]+lut[d0>>24&0xff]+'-'+
lut[d1&0xff]+lut[d1>>8&0xff]+'-'+lut[d1>>16&0x0f|0x40]+lut[d1>>24&0xff]+'-'+
lut[d2&0x3f|0x80]+lut[d2>>8&0xff]+'-'+lut[d2>>16&0xff]+lut[d2>>24&0xff]+
lut[d3&0xff]+lut[d3>>8&0xff]+lut[d3>>16&0xff]+lut[d3>>24&0xff];
}
console.log(e7())
রূপান্তরিত: http://jcward.com/UUID.js -UUID.generate()
মজার বিষয়টি হল, এলোমেলো ডেটা 16 বাইট জেনারেট করা সহজ অংশ। পুরো কৌশলটি এটি আরএফসি সম্মতিতে স্ট্রিং ফর্ম্যাটে প্রকাশ করছে এবং এটি 16 টি বাইটের এলোমেলো ডেটা, একটি অনিবন্ধিত লুপ এবং অনুসন্ধান সারণী দিয়ে সর্বাধিক দৃ .়তার সাথে সম্পন্ন হয়েছে।
আমি আশা করি আমার যুক্তিটি সঠিক - এই জাতীয় ক্লান্তিকর বিট-কর্মে ভুল করা খুব সহজ। তবে ফলাফলগুলি আমার কাছে ভাল দেখাচ্ছে। আমি আশা করি আপনি কোড অপ্টিমাইজেশনের মাধ্যমে এই উন্মাদ যাত্রাটি উপভোগ করেছেন!
পরামর্শ দিন: আমার প্রাথমিক লক্ষ্যটি সম্ভাব্য অপ্টিমাইজেশান কৌশলগুলি দেখানো এবং শেখানো ছিল। অন্যান্য উত্তরগুলি সংঘর্ষ এবং সত্যই এলোমেলো সংখ্যার মতো গুরুত্বপূর্ণ বিষয়গুলি কভার করে, যা ভাল ইউআইডিগুলি তৈরির জন্য গুরুত্বপূর্ণ।