कौन सा अधिक प्रदर्शन करने वाला है: unit_metadata_wrapper या field_get_items?


10

संस्थाओं से मान प्राप्त करने के लिए, दो तरीके हैं:

  • field_get_itemsएक क्षेत्र का उपयोग करें और प्राप्त करें
  • entity_metadata_wrapperएक क्षेत्र का उपयोग करें और प्राप्त करें

हालाँकि entity_metadata_wrapper, भाषा के अंतर को अलग कर देता है, फिर भी इसका API कभी-कभी अजीब होता है, खासकर PHP 5.3 का उपयोग करते समय। उदाहरण के लिए, लंबे टेक्स्ट फ़ील्ड का मान प्राप्त करना आमतौर पर इस मार्ग को जाता है:

$field = $wrapper->field->value();
print $field['safe_value'];

सौभाग्य से, PHP 5.4 इस सिंटैक्स का समर्थन करता है print $wrapper->field->value()['safe_value'];:।

लेकिन मेरा सवाल प्रदर्शन को लेकर अधिक चिंतित है। वे दोनों कैसे काम करते हैं? क्या वे मूल्य का अनुरोध करने पर हर बार डेटाबेस को क्वेरी करते हैं? entity_metadata_wrapperसब कुछ एक ही बार में अनुरोध करता है ? ( field_get_itemएकल-मूल्य-पुनर्प्राप्ति के लिए अधिक अनुकूल बनाना ।)

मैं ड्रुपल स्रोत में गहरी गोता लगाने के लिए पर्याप्त बहादुर नहीं हूं।


1
field_view_field()एक क्षेत्र प्रदान करने के लिए है। किसी फ़ील्ड का मान प्राप्त करने का कार्य फ़ील्ड_गेट_टाइम्स () है
kiamlaluno

और field_get_items()incurs डेटाबेस भूमि के ऊपर शून्य तो मुझे लगता है कि एक बहुत खुले और बंद मामला है :)
क्लाइव

@ क्लिक करें कि कैसे field_get_items()शून्य डेटाबेस ओवरहेड आता है? यह कहीं न कहीं इसका डेटा प्राप्त करना है, है ना?
फ्लोरियन मार्गाइन

इसके अलावा, मैं वास्तव में यह जानने में दिलचस्पी रखता हूं कि कैसे entity_metadata_wrapperकाम करता है, प्रदर्शन-वार।
फ्लोरियन मार्गाइन

2
आप में एक पूरी तरह से भरी हुई इकाई वस्तु पारित field_get_items()तो भूमि के ऊपर पहले से ही खर्च किया गया है ... यह D7 में एक गला मार्ग का एक सा ईमानदार होना है
क्लाइव

जवाबों:


12

संक्षिप्त उत्तर: field_get_items (), Unit_metadata_wrapper () की तुलना में अधिक उत्कृष्ट है।

इन कार्यों के लिए कोड देखें:

दोनों की आवश्यकता है कि आप इकाई के साथ गुजरते हैं, जो पहले ही डेटाबेस से लोड हो चुका है । उदाहरण के लिए:

$node = node_load(123);
$items = field_get_items('node', $node, 'field_my_field_name');
print $items[0]['value'];

या, जैसा कि आप पहले ही सुझा चुके हैं:

$wrapper = entity_metadata_wrapper('node', $node);
$field = $wrapper->field_my_field_name->value();
print $field['safe_value'];

इन दोनों उदाहरणों ने मुझे परेशान करने के तर्क की वजह से मुझे परेशान करने की कोशिश की, जो आपके लिए पहले से ही उपलब्ध हैं, लेकिन वे बहुत सारे मामलों में निश्चित रूप से उपयोगी हैं।

आप बस कर सकते हैं, print $node->field_my_field_name[LANGUAGE_NONE][0]['value'];लेकिन यदि क्षेत्र में कोई मान नहीं है, तो PHP नोटिस त्रुटियों को फेंक देगा, क्योंकि आप उन सरणियों का उपयोग करने का प्रयास कर रहे हैं जो मौजूद नहीं हो सकते हैं (यानी [LANGUAGE_NONE][0]['value'])। मैं अपने आप को ऐसा करने के लिए अक्सर हाल ही में मिल रहा हूँ:

if ($field = field_get_items('node', $node, 'field_my_field_name')) {
  print $field[0]['value'];
}

जो करने से बहुत साफ है:

if (isset($node->field_my_field_name[LANGUAGE_NONE]) && isset($node->field_my_field_name[LANGUAGE_NONE][0])) {
  print $node->field_my_field_name[LANGUAGE_NONE][0]['value'];
}

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

संपादित करें: चूंकि field_get_items()रन field_language()होते हैं, वास्तव में भाषा की जांच करने की तुलना में एक बड़ा प्रदर्शन हिट होगा, इसलिए, यदि आप पहले से ही जानते हैं कि $ इकाई-> भाषा मौजूद है, तो आप बस अपना स्वयं का सुपर-परफॉर्मेंट फ़ंक्शन लिख सकते हैं:

function my_super_performant_field_value_getter($entity, $field_name) {
  return isset($entity->{$field_name}[{$entity->language}]) ? $entity->{$field_name}[{$entity->language}] : FALSE;
}

ठीक है, इसलिए उन चेकों के अलावा, इकाई को एक बार लोड किया जाता है, चाहे मैं कितनी बार उनका उपयोग करूं? भले ही मैं इकाई संदर्भ का उपयोग करता हूं?
फ्लोरियन मार्गाइन

हां, यह वास्तव में डी 7 में इकाई एपीआई की एक बहुत अच्छी सुविधा है। एक बार जब आप किसी इकाई को लोड करते हैं, तो उस अनुरोध की अवधि के लिए कैश किया जाता है। इसलिए, यदि आप $node = node_load(123);1 स्क्रिप्ट में करते हैं और फिर से कहीं और करते हैं, तो आप एक पूर्ण ऑब्जेक्ट लोड और निर्माण का प्रदर्शन ओवरहेड नहीं करते हैं - ड्रुपल उस चर को मौजूदा इकाई की एक प्रति प्रदान करता है। यदि आप एक नई प्रतिलिपि लोड करना चाहते हैं , तो आपको $reset = TRUEइकाई लोड फ़ंक्शन को पास करना होगा। इसके अलावा, एक सुपर परफ़ॉर्मर गेट्टर के बारे में मेरे संपादन देखें।
चार्ली श्लिसेर

1
if (isset($node->field_my_field_name[LANGUAGE_NONE]) && isset($node->field_my_field_name[LANGUAGE_NONE][0])) {आवश्यक नहीं है, isset($node->field_my_field_name[LANGUAGE_NONE][0]पर्याप्त है।

@chx मैं सहमत हूं, लेकिन क्या यह नहीं होगा isset($node->field_my_field_name[LANGUAGE_NONE]), क्योंकि भाषा एक खाली क्षेत्र पर सेट नहीं होगी? मुझे लगता है कि यह डेल्टा है / [0]यह बेमानी है।
चार्ली श्लिसेर

1
@GilesB, अधिक डेटाबेस क्वेश्चन सबसे अक्सर जुड़ने से बेहतर नहीं हैं। एगर लोडिंग एक अनुकूलन तकनीक है। लेकिन यह कहते हुए भी, मुझे लगता है कि आपकी धारणा झूठी है और EntityMetadataWrapper शायद धीमा है, लेकिन यह उपयोग करने के लिए बहुत अच्छा है। यह भी माइक्रो ऑप्टिमाइज़ेशन है ओपी को ड्रुपल के साथ काम करते समय सोचना नहीं पड़ता है।
निकोलस रूनु
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.