tutorial - php भाषा




PHP के साथ मेमोरी को मुक्त करने में क्या बेहतर है: अनसेट() या $ var=null (8)

मुझे एहसास है कि दूसरा फ़ंक्शन कॉल के ओवरहेड से बचता है ( अपडेट , वास्तव में एक भाषा निर्माण है), लेकिन यह जानना दिलचस्प होगा कि कोई दूसरे से बेहतर है या नहीं। मैं अपने अधिकांश कोडिंग के लिए unset() का उपयोग कर रहा हूं, लेकिन मैंने हाल ही में नेट से मिले कुछ सम्मानजनक वर्गों को देखा है जो बदले में $var = null उपयोग करते हैं।

क्या कोई पसंदीदा है, और तर्क क्या है?


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

यह व्यक्तिगत अनुभव और दूसरों से भी है। here अनसेट () फ़ंक्शन की टिप्पणियां देखें।

मैं व्यक्तिगत रूप से लूप में पुनरावृत्तियों के बीच अनसेट () का उपयोग करता हूं ताकि मुझे आकार में यो-योएड होने में देरी की देरी न हो। डेटा चला गया है, लेकिन पदचिह्न बना हुआ है। अगले पुनरावृत्ति पर, स्मृति पहले से ही php द्वारा ली जा रही है और इस प्रकार, अगले चर को प्रारंभ करने के लिए तेज़ी से।


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

जीसी को स्मृति एकत्र करने में सक्षम करने के लिए time_nanosleep का उपयोग करें। परिवर्तनीय को शून्य पर सेट करना वांछनीय है।

उत्पादन सर्वर पर परीक्षण किया गया, मूल रूप से नौकरी 50 एमबी खपत थी और फिर रुक गई थी। नैनोस्लीप के बाद 14 एमबी का इस्तेमाल स्मृति स्मृति खपत था।

किसी को यह कहना चाहिए कि यह जीसी व्यवहार पर निर्भर करता है जो PHP संस्करण से संस्करण में बदल सकता है। लेकिन यह PHP 5.3 ठीक पर काम करता है।

जैसे। यह नमूना (कोड लिया गया VirtueMart2 google फ़ीड)

for($n=0; $n<count($ids); $n++)
{
    //unset($product); //usefull for arrays
    $product = null
    if( $n % 50 == 0 )
    {
        // let GC do the memory job
        //echo "<mem>" . memory_get_usage() . "</mem>";//$ids[$n];
        time_nanosleep(0, 10000000);
    }

    $product = $productModel->getProductSingle((int)$ids[$n],true, true, true);
    ...

मुझे अभी भी इस बारे में संदेह है, लेकिन मैंने इसे अपनी स्क्रिप्ट पर आजमाया है और मैं यह जानने के लिए xdebug का उपयोग कर रहा हूं कि यह मेरे ऐप मेमोरी उपयोग को कैसे प्रभावित करेगा। स्क्रिप्ट इस तरह मेरे फ़ंक्शन पर सेट है:

function gen_table_data($serv, $coorp, $type, $showSql = FALSE, $table = 'ireg_idnts') {
    $sql = "SELECT COUNT(`operator`) `operator` FROM $table WHERE $serv = '$coorp'";
    if($showSql === FALSE) {
        $sql = mysql_query($sql) or die(mysql_error());
        $data = mysql_fetch_array($sql);
        return $data[0];
    } else echo $sql;
}

और मैं return कोड से पहले अनसेट जोड़ता हूं और यह मुझे देता है: 160200 तो मैं इसे $sql = NULL साथ बदलने की कोशिश करता हूं और यह मुझे देता है: 160224 :)

लेकिन जब मैं अनसेट () या NULL का उपयोग नहीं कर रहा हूं, तो इस तुलनात्मक पर कुछ अद्वितीय है, xdebug मुझे स्मृति उपयोग के रूप में 160144 दें

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

अगर मैं गलत हूं, तो मुझे सुधारें, धन्यवाद


मैंने unset और =null लिए एक नया प्रदर्शन परीक्षण बनाया, क्योंकि टिप्पणियों में उल्लेखित लिखित में एक त्रुटि है (तत्वों की पुनर्निर्माण)। मैंने सरणी का उपयोग किया, जैसा कि आप देखते हैं कि इससे कोई फर्क नहीं पड़ता।

<?php
$arr1 = array();
$arr2 = array();
for ($i = 0; $i < 10000000; $i++) {
    $arr1[$i] = 'a';
    $arr2[$i] = 'a';
}

$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
    $arr1[$i] = null;
}
$elapsed = microtime(true) - $start;

echo 'took '. $elapsed .'seconds<br>';

$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
    unset($arr2[$i]);
}
$elapsed = microtime(true) - $start;

echo 'took '. $elapsed .'seconds<br>';

लेकिन मैं केवल PHP 5.5.9 सर्वर पर इसका परीक्षण कर सकता हूं, परिणाम: - 4.45715713500 9 8 सेकेंड लिया - 4.4425978660583 सेकंड लिया

मैं पठनीयता के कारणों के लिए परेशान करना पसंद करता हूं।


यह सरणी तत्वों के साथ एक अंतर बनाता है।

इस उदाहरण पर विचार करें

$a = array('test' => 1);
$a['test'] = NULL;
echo "Key test ", array_key_exists('test', $a)? "exists": "does not exist";

यहां, कुंजी 'परीक्षण' अभी भी मौजूद है। हालांकि, इस उदाहरण में

$a = array('test' => 1);
unset($a['test']);
echo "Key test ", array_key_exists('test', $a)? "exists": "does not exist";

कुंजी अब मौजूद नहीं है।


रिकॉर्ड के लिए, और उस समय को छोड़कर जो इसे लेता है:

<?php
echo "<hr>First:<br>";
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";      
echo memory_get_peak_usage() . "<br>\n"; 
echo "<hr>Unset:<br>";
unset($x);
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";      
echo memory_get_peak_usage() . "<br>\n"; 
echo "<hr>Null:<br>";
$x=null;
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";      
echo memory_get_peak_usage() . "<br>\n";

echo "<hr>function:<br>";
function test() {
    $x = str_repeat('x', 80000);
}
echo memory_get_usage() . "<br>\n";      
echo memory_get_peak_usage() . "<br>\n"; 

echo "<hr>Reasign:<br>";
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";      
echo memory_get_peak_usage() . "<br>\n"; 

यह वापस आता है

First:
438296
438352
Unset:
438296
438352
Null:
438296
438352
function:
438296
438352
Reasign:
438296
520216 <-- double usage.

निष्कर्ष, उम्मीद के अनुसार शून्य और अनसेट मुक्त स्मृति दोनों (केवल निष्पादन के अंत में नहीं)। साथ ही, एक चर को पुन: असाइन करने से मूल्य कुछ बिंदु पर दो बार होता है (520216 बनाम 438352)


unset वास्तव में एक समारोह नहीं है, लेकिन एक भाषा निर्माण । यह return या एक include से अधिक फ़ंक्शन कॉल नहीं है।

प्रदर्शन समस्याओं के अलावा, unset का उपयोग करके आपके कोड का इरादा बहुत स्पष्ट हो जाता है।


<?php
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
    $a = 'a';
    $a = NULL;
}
$elapsed = microtime(true) - $start;

echo "took $elapsed seconds\r\n";



$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
    $a = 'a';
    unset($a);
}
$elapsed = microtime(true) - $start;

echo "took $elapsed seconds\r\n";
?>

ऐसा लगता है कि ऐसा लगता है कि "= शून्य" तेज है।

PHP 5.4 परिणाम:

  • 0.88389301300049 सेकंड लिया
  • 2.1757180690765 सेकंड लिया

PHP 5.3 परिणाम:

  • 1.7235369682312 सेकंड लिया
  • 2.9490 9 5 9 644318 सेकंड लिया

PHP 5.2 परिणाम:

  • 3.0069220066071 सेकंड लिया
  • 4.7002630233765 सेकंड लिया

PHP 5.1 परिणाम:

  • 2.6272349357605 सेकंड लिया
  • 5.0403649806976 सेकंड लिया

चीजें PHP 5.0 और 4.4 के साथ अलग दिखने लगती हैं।

5.0:

  • 10.038941144 9 43 सेकंड लिया
  • 7.0874409675598 सेकंड लिया

4.4:

  • 7.5352551937103 सेकंड लिया
  • 6.6245851516724 सेकंड लिया

ध्यान रखें microtime (true) PHP 4.4 में काम नहीं करता है इसलिए मुझे php.net/microtime / example # 1 में दिए गए microtime_float उदाहरण का उपयोग करना पड़ा।





php