เพื่อความเป็นธรรมมันขึ้นอยู่กับประเภทของข้อมูลที่คุณมี ผลลัพธ์ในคำตอบอื่น ๆ ถูกต้อง (มากหรือน้อย) * ฉันจะวางโค้ดทดสอบที่ด้านล่างเพื่อความชัดเจน
สิ่งสำคัญที่นี่คือคุณสามารถประหยัดหน่วยความจำได้พอสมควรหากคุณใช้วัตถุที่กำหนดไว้ล่วงหน้าการแลกเปลี่ยนคือความจริงที่ว่าคุณต้องกำหนดโครงสร้างที่แน่นอน
พิจารณาผลการทดสอบต่อไปนี้:
static obj: 0.04223108291626
memory: 164920
object(staticSet)
["aaa"]=>
string(3) "aaa"
["bbb"]=>
string(3) "bbb"
["ccc"]=>
string(6) "aaabbb"
}
---------------------------------------
static obj with an additional prop: 0.042968988418579
memory: 524920
object(staticSet2)
["aaa"]=>
string(3) "aaa"
["bbb"]=>
string(3) "bbb"
["ddd"]=>
string(6) "aaabbb"
}
---------------------------------------
ฉันอาจจะผิดที่นี่ฉันไม่ได้มองหาแหล่งที่มาของ PHP แต่ฉันเชื่อว่าเท่าที่ PHP เกี่ยวข้องทุกอย่างเป็นอาร์เรย์ วัตถุที่กำหนดไว้ล่วงหน้าเป็นเพียงอาร์เรย์ที่กำหนดไว้อย่างดี ข้อสังเกตที่น่าสนใจคือประเภทค่าไม่มีผลเช่น ค่าสตริงเป็น '1' จะใช้หน่วยความจำจำนวนเท่ากันกับค่าบูลของ true
ทำไม? อย่างที่ฉันได้กล่าวไว้ก่อน PHP คืออาร์เรย์ดังนั้นหากคุณมีวัตถุที่มีฟังก์ชัน setter สิ่งที่ PHP (เวอร์ชันที่เรียบง่าย) ทำคือ:
$objects = ['objectName' => [
'aaa' => '',
'bbb' => '',
'ccc' => '',
'setValue:f' => function('name', 'value') { ... }
]
];
ทุกครั้งที่คุณดำเนินการคุณจะค้นหาคีย์ฟังก์ชันที่ค้นหาชื่อเสารวมถึงการตรวจสอบความถูกต้องสำหรับประเภทของเสา ฯลฯ ในพื้นหลัง การประหยัดหน่วยความจำในออบเจ็กต์ที่กำหนดไว้ล่วงหน้ามาจากการกำหนดอาร์เรย์ของความยาวที่ตั้งไว้ (เป็นไปไม่ได้ใน PHP) แทนที่จะจัดสรรหน่วยความจำส่วนหนึ่ง
สรุป:
วัตถุที่หยุดนิ่ง:เย้! เราประหยัดหน่วยความจำ! แต่ถ้าคุณพยายามเพิ่มสิ่งที่อยู่นอกคำจำกัดความมันก็จะใหญ่ขึ้นแล้ว stdClass
['aaa'] into [['aaa'],['bbb']]
อาร์เรย์:ถ้าคุณเขียนด้วย PHP คุณควรรักพวกเขามากกว่านี้แม้แต่สตริงก็เป็นอาร์เรย์ของอักขระใน PHP
วัตถุ:ออบเจ็กต์มีฟังก์ชันที่ยอดเยี่ยมเป็นวิธีที่ยอดเยี่ยมในการจัดระเบียบรหัสของคุณให้เป็นระเบียบสะอาดเป็นโมดูล แต่อย่างที่ทราบกันดีว่า "มีพลังมหาศาล ... ".
ในที่สุดรหัสทดสอบของฉันและ '*' ดูเหมือนผู้คนจะลืมไปว่าถ้าคุณไม่ล้างตัวแปรของคุณในขณะที่สคริปต์กำลังทำงานอยู่มันจะยังคงอยู่ในหน่วยความจำในขณะที่มันจะไม่ส่งผลกระทบต่อเวลาดำเนินการ (มาก) มันจะส่งผลต่อการวัดหน่วยความจำ ดังนั้นในขณะที่เรียกใช้ unset โปรไฟล์หน่วยความจำ () คือเพื่อนของคุณ
<?php
error_reporting(E_ALL);
ini_set('display_errors',1);
$noOfObjects = 1000;
$noOfOperations = 1000;
class set {
public function setKey($key, $value) {
$this->{$key} = $value;
}
public function readKey($name) {
return $this->{$name};
}
}
class staticSet {
public string $aaa;
public string $bbb;
public string $ccc;
}
class staticSet2 {
public string $aaa;
public string $bbb;
}
class staticSet3 {
public bool $aaa;
public bool $bbb;
public bool $ccc;
}
$arraysOf=[];
$t0 = microtime(true);
$start=memory_get_usage();
for ($i=0; $i<$noOfObjects; $i++) {
$z = array();
for ($j=0; $j<$noOfOperations; $j++) {
$z['aaa'] = 'aaa';
$z['bbb'] = 'bbb';
$z['ccc'] = $z['aaa'].$z['bbb'];
}
$arraysOf[]=$z;
}
$end=memory_get_usage();
echo 'arrays: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
$arraysOf=[];
$t0 = microtime(true);
$start=memory_get_usage();
for ($i=0; $i<$noOfObjects; $i++) {
$z = new set();
for ($j=0; $j<$noOfOperations; $j++) {
$z->setKey('aaa','aaa');
$z->setKey('bbb','bbb');
$z->setKey('ccc',$z->readKey('aaa').$z->readKey('bbb'));
}
$arraysOf[]=$z;
}
$end=memory_get_usage();
echo 'dynamic obj: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
$arraysOf=[];
$t0 = microtime(true);
$start=memory_get_usage();
for ($i=0; $i<$noOfObjects; $i++) {
$z = new staticSet();
for ($j=0; $j<$noOfOperations; $j++) {
$z->{'aaa'} = 'aaa';
$z->{'bbb'} = 'bbb';
$z->{'ccc'} = $z->{'aaa'}.$z->{'bbb'};
}
$arraysOf[]=$z;
}
$end=memory_get_usage();
echo 'static obj: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
$arraysOf=[];
$t0 = microtime(true);
$start=memory_get_usage();
for ($i=0; $i<$noOfObjects; $i++) {
$z = new staticSet2();
for ($j=0; $j<$noOfOperations; $j++) {
$z->{'aaa'} = 'aaa';
$z->{'bbb'} = 'bbb';
$z->{'ddd'} = $z->{'aaa'}.$z->{'bbb'};
}
$arraysOf[]=$z;
}
$end=memory_get_usage();
echo 'static obj with an additional prop: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
$arraysOf=[];
$t0 = microtime($noOfObjects);
$start=memory_get_usage();
for ($i=0; $i<$noOfObjects; $i++) {
$z = new Ds\Map();
for ($j=0; $j<$noOfOperations; $j++) {
$z->put('aaa','aaa');
$z->put('bbb','bbb');
$z->put('ccc',$z->get('aaa').$z->get('bbb'));
}
$arraysOf[]=$z;
}
$end=memory_get_usage();
echo 'Ds\Map: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
$arraysOf=[];
$t0 = microtime(true);
$start=memory_get_usage();
for ($i=0; $i<$noOfObjects; $i++) {
$z = new staticSet();
for ($j=0; $j<$noOfOperations; $j++) {
$z->{'aaa'} = '1';
$z->{'bbb'} = '1';
$z->{'ccc'} = ($z->{'aaa'} && $z->{'bbb'});
}
$arraysOf[]=$z;
}
$end=memory_get_usage();
echo 'static obj with bool values: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
$arraysOf=[];
$t0 = microtime(true);
$start=memory_get_usage();
for ($i=0; $i<$noOfObjects; $i++) {
$z = new staticSet3();
for ($j=0; $j<$noOfOperations; $j++) {
$z->{'aaa'} = '1';
$z->{'bbb'} = '1';
$z->{'ccc'} = ($z->{'aaa'} && $z->{'bbb'});
}
$arraysOf[]=$z;
}
$end=memory_get_usage();
echo 'static obj with defined bool values: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
$arraysOf=[];
$t0 = microtime(true);
$start=memory_get_usage();
for ($i=0; $i<$noOfObjects; $i++) {
$z = array('aaa' => '','bbb' => '','ccc' => '');
for ($j=0; $j<$noOfOperations; $j++) {
$z['aaa'] = 'aaa';
$z['bbb'] = 'bbb';
$z['ccc'] = $z['aaa'].$z['bbb'];
}
$arraysOf[]=$z;
}
$end=memory_get_usage();
echo 'predefined array: '.(microtime(true) - $t0).PHP_EOL;
echo 'memory: '.($end-$start).PHP_EOL;
var_dump($z);
unset($t0,$start,$end,$z,$arraysOf);
echo '---------------------------------------'.PHP_EOL;
echo 'phpversion '.phpversion().PHP_EOL;