2012-07-05 22 views
13

में UUID को सम्मिलित करने और लाने के लिए कैसे करें मैं कोर डेटा में यूयूआईडी स्टोर और खोज करने का एक प्रभावी तरीका ढूंढ रहा हूं। उन यूयूआईडी वितरित सिस्टम में कई आईओएस उपकरणों द्वारा उत्पन्न होते हैं। उनमें से प्रत्येक डिवाइस लगभग 20-50k यूयूआईडी स्टोर कर सकता है।कोर डेटा

ऐसा नहीं है कि UUID कोर डाटा में स्ट्रिंग के रूप में संग्रहीत करने के लिए उस पर अनुक्रमण की दक्षता को नुकसान होगा स्पष्ट है। लेकिन शोध की एक श्रृंखला के बाद मैंने पाया कि कोर डेटा (और इसे इंडेक्स) में बाइनरी डेटा के रूप में यूयूआईडी स्टोर करने से स्ट्रिंग के रूप में इसे संग्रहीत करने से कम कुशल हो सकता है।

SQLit में कोई बायनरी-तरह या VARBINARY की तरह डेटा प्रकार समर्थित है के रूप में वहाँ है। मुझे लगता है कि कोर डेटा में किसी भी बाइनरी डेटा प्रकार का डेटा SQLit में बीएलओबी के रूप में संग्रहीत किया जाता है। चूंकि बीएलओबी अनुक्रमित होने के लिए सबसे धीमे डेटा प्रकार हो सकता है, इससे प्रदर्शन पर बुरा प्रभाव पड़ेगा।

तो क्या कोई जवाब देने में मदद कर सकता है, क्या कोर डेटा में यूयूआईडी स्टोर करने का एक और अधिक प्रभावी तरीका है?

+0

आप जानते हैं कि UDID के लिए उपयोग iOS 5 के बंद कर दिया गया है, हाँ? –

+3

ओपी यूयूआईडी के बारे में बात कर रहा है जो यूडीआईडी ​​से अलग हैं। –

+0

@ जॉडी हैगिन, आप सही हैं। यूयूआईडी मैंने उल्लेख किया है कि मेरे ऐप द्वारा बनाए गए प्रबंधित ऑब्जेक्ट्स के लिए सार्वभौमिक अद्वितीय पहचानकर्ता है। –

उत्तर

30

उन्हें ASCII स्ट्रिंग के रूप में स्टोर करें, और फ़ील्ड को एक अनुक्रमणिका बनाएं।

संपादित

ओह नहीं, मैं इस बारे में कुछ poking कर रही होती है और इस बारे में जाना। क्या शर्मनाक जवाब है। मैं उस दिन एक मूड में थोड़ा सा होना चाहिए था। अगर मैं कर सकता, तो मैं इसे हटा दूंगा और आगे बढ़ जाऊंगा। हालांकि, यह संभव नहीं है, इसलिए मैं एक अद्यतन का एक स्निप प्रदान करूंगा।

सबसे पहले, पता है कि "कुशल" है एक ही रास्ता को मापने के लिए, इस कार्यक्रम समय और स्थान के साथ ही स्रोत कोड जटिलता और प्रोग्रामर प्रयास पर विचार है।

सौभाग्य से, यह एक बहुत आसान है।

मैंने एक बहुत ही सरल ओएसएक्स आवेदन लिखा था। मॉडल में एक विशेषता है: identifier

यदि आप अपनी विशेषता को इंडेक्स के रूप में चिह्नित नहीं करते हैं, तो इनमें से कोई भी मामला नहीं है। दुकान बनाने के दौरान इसमें बहुत अधिक समय लगेगा, लेकिन यह प्रश्नों को बहुत तेज बना देगा।

इसके अलावा, ध्यान दें कि एक द्विआधारी विशेषता के लिए एक विधेय बनाने एक स्ट्रिंग के लिए बनाने जैसा बिल्कुल वैसा ही है:

fetchRequest.predicate = 
    [NSPredicate predicateWithFormat:@"identifier == %@", identifier]; 

आवेदन बहुत सरल है। सबसे पहले, यह एन ऑब्जेक्ट बनाता है, और पहचानकर्ता विशेषता को यूयूआईडी असाइन करता है। यह एमओसी हर 500 वस्तुओं को बचाता है। फिर हम सभी पहचानकर्ताओं को एक सरणी में स्टोर करते हैं और उन्हें यादृच्छिक रूप से घुमाते हैं। पूरी सीडी स्टैक को स्मृति से सभी को हटाने के लिए पूरी तरह से फेंक दिया जाता है।

इसके बाद, हम ढेर फिर से निर्माण, और फिर पहचानकर्ता से अधिक पुनरावृति, और एक सरल लाने से करते हैं। Fetch ऑब्जेक्ट का निर्माण किया जाता है, एक वस्तु को लाने के लिए एक साधारण भविष्यवाणी के साथ। यह सब एक fetoreleasepool के अंदर किया जाता है ताकि प्रत्येक fetch को यथासंभव प्राचीन माना जा सके (मैं स्वीकार करता हूं कि सीडी कैश के साथ कुछ बातचीत होगी)। यह इतना महत्वपूर्ण नहीं है, क्योंकि हम सिर्फ विभिन्न तकनीकों की तुलना कर रहे हैं।

बाइनरी पहचानकर्ता UUID के लिए 16-बाइट्स है।

यूयूआईडी स्ट्रिंग एक 36-बाइट स्ट्रिंग है, [uuid UUIDString] को कॉल करने का नतीजा है, और ऐसा लगता है (B85E91F3-4A0A-4ABB-A049-83B2A8E6085E)।

Base64 स्ट्रिंग एक 24-बाइट स्ट्रिंग, आधार -64 16-बाइट UUID बाइनरी डेटा एन्कोडिंग का परिणाम है, और यह एक ही UUID के लिए इस (uF6R80oKSrugSYOyqOYIXg ==) की तरह दिखता है।

गणना उस दौड़ के लिए वस्तुओं की संख्या है।

SQLite आकार वास्तविक स्क्लाइट फ़ाइल का आकार है।

वाल आकार कितना बड़ा वाल (लिखने-आगे-लॉगिंग) फ़ाइल हो जाता है - बस FYI करें ...

बनाएं सेकंड की संख्या की बचत सहित डेटाबेस, तैयार करना है।

क्वेरी प्रत्येक ऑब्जेक्ट को क्वेरी करने के लिए सेकंड की संख्या है। जो एक डेटाबेस के लिए उम्मीद की जा करने के लिए है -

Data Type  | Count (N) | SQLite Size | WAL Size | Create | Query 
--------------+-----------+-------------+-----------+---------+--------- 
Binary  | 100,000 | 5,758,976 | 5,055,272 | 2.6013 | 9.2669 
Binary  | 1,000,000 | 58,003,456 | 4,783,352 | 59.0179 | 96.1862 
UUID String | 100,000 | 10,481,664 | 4,148,872 | 3.6233 | 9.9160 
UUID String | 1,000,000 | 104,947,712 | 5,792,752 | 68.5746 | 93.7264 
Base64 String | 100,000 | 7,741,440 | 5,603,232 | 3.0207 | 9.2446 
Base64 String | 1,000,000 | 77,848,576 | 4,931,672 | 63.4510 | 94.5147 

यहाँ नोट करने के लिए पहली बात यह है कि वास्तविक डेटाबेस आकार बाइट्स संग्रहीत (1600000 और 16,000,000) से भी ज्यादा बड़ा है। अतिरिक्त भंडारण की मात्रा कुछ हद तक आपकी वास्तविक वस्तुओं के आकार के सापेक्ष होगी ... यह केवल पहचानकर्ता को स्टोर करता है ताकि ओवरहेड का प्रतिशत अधिक हो)।

दूसरा, संदर्भ के लिए, गति के मुद्दों पर, एक ही 1,000,000 ऑब्जेक्ट क्वेरी कर रहा है, लेकिन प्राप्त करने में ऑब्जेक्ट-आईडी का उपयोग करने में लगभग 82 सेकंड लगते हैं (उस के बीच का अंतर अंतर और existingObjectWithID:error: पर कॉल करना जो 0.3065 सेकंड)।

आपको चल रहे कोड पर उपकरणों के न्यायिक उपयोग सहित अपने डेटाबेस को प्रोफ़ाइल करना चाहिए। मुझे लगता है कि अगर मैंने कई रन बनाए हैं तो संख्या कुछ अलग होगी, लेकिन वे इतने करीब हैं कि इस विश्लेषण के लिए यह आवश्यक नहीं है।

हालांकि, इन संख्याओं के आधार पर, कोड निष्पादन के लिए दक्षता माप देखें।

  • जैसा कि अपेक्षित है, कच्चे यूयूआईडी बाइनरी डेटा को संग्रहीत करना अंतरिक्ष के मामले में अधिक कुशल है।
  • निर्माण के समय बहुत करीब (अंतर समय तार और अतिरिक्त भंडारण स्थान की आवश्यकता बनाने के लिए पर आधारित होने की दिखाई दे रहा है)।
  • क्वेरी बार लगभग समान लगते हैं, एक छोटा सा धीमी प्रतीत होने बाइनरी स्ट्रिंग के साथ। मुझे लगता है कि यह मूल चिंता थी - एक बाइनरी विशेषता पर एक प्रश्न कर रहा था।

बाइनरी बहुत से स्थान जीतता है, और इसे निर्माण समय और क्वेरी समय दोनों पर एक करीबी ड्रॉ माना जा सकता है। अगर हम उन पर विचार करते हैं, तो द्विआधारी डेटा संग्रहित करना स्पष्ट विजेता है।

स्रोत कोड जटिलता और प्रोग्रामर समय के बारे में कैसे?

ठीक है, आप आईओएस और OSX का आधुनिक संस्करण उपयोग कर रहे हैं, वहाँ वास्तव में कोई अंतर विशेष रूप से NSUUID पर एक साधारण श्रेणी के साथ है।

हालांकि, वहाँ आप के लिए एक विचार है, और है कि डेटाबेस में डेटा का उपयोग कर में आसानी है। जब आप बाइनरी डेटा स्टोर करते हैं, तो डेटा पर एक अच्छा दृश्य प्राप्त करना मुश्किल होता है।

तो, किसी कारण से, अगर आप चाहते हैं, डेटाबेस में डेटा मनुष्य के लिए एक अधिक कुशल तरीके से संग्रहीत करने के लिए है, तो यह भंडारण के रूप में एक स्ट्रिंग एक बेहतर विकल्प है। तो, आप बेस 64 एन्कोडिंग (या कुछ अन्य एन्कोडिंग) पर विचार करना चाह सकते हैं - हालांकि याद रखें कि यह पहले से ही बेस -256-एन्कोडिंग में है)।

Fwiw, यहां दोनों NSData और base64 स्ट्रिंग के रूप में UUID के लिए आसान पहुँच प्रदान करने के लिए एक उदाहरण के श्रेणी है:

- (NSData*)data 
{ 
    uuid_t rawuuid; 
    [self getUUIDBytes:rawuuid]; 
    return [NSData dataWithBytes:rawuuid length:sizeof(rawuuid)]; 
} 

- (NSString*)base64String 
{ 
    uuid_t rawuuid; 
    [self getUUIDBytes:rawuuid]; 
    NSData *data = [NSData dataWithBytesNoCopy:rawuuid length:sizeof(rawuuid) freeWhenDone:NO]; 
    return [data base64EncodedStringWithOptions:0]; 
} 

- (instancetype)initWithBase64String:(NSString*)string 
{ 
    NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:0]; 
    if (data.length == sizeof(uuid_t)) { 
     return [self initWithUUIDBytes:data.bytes]; 
    } 
    return self = nil; 
} 

- (instancetype)initWithString:(NSString *)string 
{ 
    if ((self = [self initWithUUIDString:string]) == nil) { 
     self = [self initWithBase64String:string]; 
    } 
    return self; 
} 
+0

अच्छी सलाह, धन्यवाद। यह कोर डेटा के लिए आधे प्रयासों को बचा सकता है। लेकिन मैं अभी भी सोच रहा हूं कि कैसे ASCII स्ट्रिंग को कोर डेटा से SQLit में मैप किया गया है। मुझे लगता है कि केवल एक असली परीक्षण चल रहा है बता सकते हैं। –

+0

सामान्य रूप से, आप यह सुनिश्चित करना चाहते हैं कि आपके द्वारा खोजे जाने वाले तारों को यूनिकोड को बाहर करने के लिए सामान्यीकृत किया गया हो। इसके अलावा, केस असंवेदनशील खोजों का उपयोग करने के बजाय, डेटा को यूनिकोड और केस को हटाने के लिए सामान्य करें। BEGINSWITH, आदि के बजाय < and > का उपयोग करें। 2010, 2011 और 2012 डब्ल्यूडब्ल्यूडीसी वीडियो में बहुत अच्छे सुझाव हैं। मैं अत्यधिक उन्हें सलाह देते हैं। –

+0

hi @JodyHagins क्या आप इस विषय के बारे में डब्ल्यूडब्ल्यूडीसी वीडियो के नाम निर्दिष्ट कर सकते हैं। उनमें से बहुत सारे हैं। अग्रिम में धन्यवाद। –