سؤال

ما هو الأفضل للاستخدام في PHP، مصفوفة ثنائية الأبعاد أم فئة؟لقد قمت بتضمين مثال على ما أعنيه بهذا.

// Using a class
class someClass
{
    public  $name;
    public  $height;
    public  $weight;

    function __construct($name, $height, $weight)
    {
        $this -> name       = $name;
        $this -> height = $height;
        $this -> weight = $weight;
    }
}

$classArray[1] = new someClass('Bob', 10, 20);
$classArray[2] = new someClass('Fred', 15, 10);
$classArray[3] = new someClass('Ned', 25, 30);


// Using a 2D array
$normalArray[1]['name'] = 'Bob';
$normalArray[1]['height']   = 10;
$normalArray[1]['weight']   = 20;

$normalArray[2]['name'] = 'Fred';
$normalArray[2]['height']   = 15;
$normalArray[2]['weight']   = 10;

$normalArray[3]['name'] = 'Ned';
$normalArray[3]['height']   = 25;
$normalArray[3]['weight']   = 30;

بافتراض أن شخصًا ما لم يخرج ويظهر أن الفصول الدراسية بطيئة للغاية، يبدو أن الفصل يفوز.

ليس لدي أي فكرة عن الإجابة التي يجب أن أقبلها لأنني قمت للتو بالتصويت عليها جميعًا.


وقد كتبت الآن صفحتين متطابقتين تقريبًا، واحدة باستخدام المصفوفة ثنائية الأبعاد (مكتوبة قبل نشر هذا السؤال) والآن واحدة باستخدام فصل دراسي ويجب أن أقول إن الفصل ينتج كودًا أجمل بكثير.ليس لدي أي فكرة عن مقدار النفقات العامة التي سيتم إنشاؤها ولكني أشك في أنها ستنافس تحسين الكود نفسه.

شكرًا لك على مساعدتي في جعلي مبرمجًا أفضل.

هل كانت مفيدة؟

المحلول

"الفصل" الذي قمت بإنشائه أعلاه هو ما يستخدمه معظم الأشخاص البنية ل في لغات أخرى.لست متأكدًا من الآثار المترتبة على الأداء في PHP، على الرغم من أنني أظن أن إنشاء مثيل للكائنات ربما يكون أكثر تكلفة هنا، ولو قليلاً.

ومع ذلك، إذا كانت التكلفة منخفضة نسبيًا، فمن الأسهل قليلاً إدارة الكائنات، في رأيي.

أنا أقول ما يلي فقط بناءً على العنوان وسؤالك، ولكن:ضع في اعتبارك أن الفئات توفر ميزة الأساليب والتحكم في الوصول أيضًا.لذا، إذا كنت تريد التأكد من أن الأشخاص لا يغيرون الأوزان إلى أرقام سالبة، فيمكنك إجراء ذلك weight الحقل خاص وتوفير بعض طرق الوصول، مثل getWeight() و setWeight().داخل setWeight(), ، يمكنك إجراء بعض التحقق من القيمة، مثل:

public function setWeight($weight)
{
    if($weight >= 0)
    {
        $this->weight = $weight;
    }
    else
    {
        // Handle this scenario however you like
    }
}

نصائح أخرى

يعتمد الأمر بالضبط على ما تعنيه بكلمة "أفضل".سأختار الطريقة الموجهة للكائنات (باستخدام الفئات) لأنني أجد أنها تجعل التعليمات البرمجية أنظف (على الأقل في رأيي).ومع ذلك، لست متأكدًا من عقوبات السرعة التي قد تكون مفروضة على هذا الخيار.

على العموم أنا أتبع هذه القاعدة:

1) اجعله فئة إذا كانت أجزاء متعددة من تطبيقك تستخدم بنية البيانات.

2) اجعلها مصفوفة ثنائية الأبعاد إذا كنت تستخدمها للمعالجة السريعة للبيانات في جزء واحد من تطبيقك.

إنها السرعة التي أفكر فيها في الغالب، بالنسبة لأي شيء أكثر تعقيدًا مما لدي هنا، ربما سأختار الفصول الدراسية ولكن السؤال هو، ما هي تكلفة الفصل الدراسي؟

قد يبدو هذا بمثابة التحسين السابق لأوانه.لن يتلقى تطبيقك أي أداء حقيقي في كلتا الحالتين، ولكن استخدام فئة يتيح لك استخدام أساليب getter وsetter وسيكون بشكل عام أفضل لتغليف التعليمات البرمجية وإعادة استخدام التعليمات البرمجية.

مع المصفوفات التي تتكبد تكلفة من الصعب قراءة التعليمات البرمجية والحفاظ عليها، لا يمكنك وحدة اختبار التعليمات البرمجية بسهولة ومع بنية فئة جيدة يجب أن يجد المطورون الآخرون أنه من الأسهل فهم ما إذا كانوا بحاجة إلى تنفيذها.

وعندما تحتاج لاحقًا إلى إضافة طرق أخرى للتعامل معها، فلن يكون لديك بنية لتوسيعها.

الفئة التي لديك ليست فئة حقيقية من حيث OO - لقد تم إنشاؤها للتو لتأخذ مساحة متغيرات المثيل.

ومع ذلك - ربما لا توجد مشكلة كبيرة تتعلق بالسرعة - فهي مجرد شيء يتعلق بالأسلوب في مثالك.

الشيء المثير للاهتمام - هو أنك إذا قمت ببناء الكائن ليكون فئة "شخص" حقيقية - وفكرت في السمات والإجراءات الأخرى التي قد تريدها من فئة الشخص - فإنك ستلاحظ ليس فقط أداء الأسلوب - كتابة التعليمات البرمجية - ولكن وأيضا سرعة الأداء.

إذا كان الكود الخاص بك يستخدم الكثير من الوظائف التي تعمل على تلك السمات (الاسم/الطول/الوزن)، فقد يكون استخدام الفئة خيارًا جيدًا.

حسنًا، إذا كنت تستخدم الفئات كمجرد بديل للمصفوفات، فأنت لست قريبًا من OOP.جوهر OOP هو أن الكائنات لديها المعرفة والمسؤولية، ويمكنها فعل الأشياء والتعاون مع الفئات الأخرى.تمتلك كائناتك المعرفة فقط ولا يمكنها فعل أي شيء آخر غير وجودها في وضع الخمول، ومع ذلك يبدو أنها مرشحة جيدة لموفري الثبات (الكائنات التي تعرف كيفية تخزين/استرداد نفسها من/إلى قاعدة البيانات).

لا تقلق بشأن الأداء أيضًا.الكائنات في PHP سريعة وخفيفة الوزن والأداء بشكل عام مبالغ فيه كثيرًا.إن توفير وقتك كمبرمج باستخدام النهج الصحيح أرخص من توفير ميكروثانية في برنامجك مع بعض التعليمات البرمجية الغامضة التي يصعب تصحيحها وإصلاحها.

معظم الاختبارات التي تقوم فيها صفائف الوقت مقابل الفئات باختبار مثيلاتها فقط.بمجرد أن تبدأ فعليًا في فعل شيء معهم.

لقد كنت "نقيًا" أستخدم المصفوفات فقط لأن الأداء كان أفضل بكثير.لقد كتبت الكود التالي لتبرير نفسي لتبرير المتاعب الإضافية لعدم استخدام الفئات (على الرغم من أنها أسهل على المبرمج)

دعنا نقول فقط أنني فوجئت جدًا بالنتائج!

    <?php
$rx = "";
$rt = "";
$rf = "";

$ta = 0; // total array time
$tc = 0; // total class time

// flip these to test different attributes
$test_globals = true;
$test_functions = true;
$test_assignments = true;
$test_reads = true;


// define class


class TestObject
{
  public $a;
  public $b;
  public $c;
  public $d;
  public $e;
  public $f;

  public function __construct($a,$b,$c,$d,$e,$f)
  {
    $this->a = $a;
    $this->b = $b;
    $this->c = $c;
    $this->d = $d;
    $this->e = $e;
    $this->f = $f;
  }

  public function setAtoB()
  {
      $this->a = $this->b;
  }
}

// begin test

echo "<br>test reads: " . $test_reads;
echo "<br>test assignments: " . $test_assignments;
echo "<br>test globals: " . $test_globals;
echo "<br>test functions: " . $test_functions;
echo "<br>";

for ($z=0;$z<10;$z++)
{
    $starta = microtime(true);

    for ($x=0;$x<100000;$x++)
    {
        $xr = getArray('aaa','bbb','ccccccccc','ddddddddd','eeeeeeee','fffffffffff');

        if ($test_assignments)
        {
            $xr['e'] = "e";
            $xr['c'] = "sea biscut";
        }

        if ($test_reads)
        {
            $rt = $x['b'];
            $rx  = $x['f'];
        }

        if ($test_functions) { setArrAtoB($xr); }
        if ($test_globals) { $rf = glb_arr(); }
    }
    $ta = $ta + (microtime(true)-$starta);
    echo "<br/>Array time = " . (microtime(true)-$starta) . "\n\n";


    $startc = microtime(true);

    for ($x=0;$x<100000;$x++)
    {
        $xo = new TestObject('aaa','bbb','ccccccccc','ddddddddd','eeeeeeee','fffffffffff');

        if ($test_assignments)
        {
            $xo->e = "e";
            $xo->c = "sea biscut";
        }

        if ($test_reads)
        {
            $rt = $xo->b;
            $rx = $xo->f;
        }

        if ($test_functions) { $xo->setAtoB(); }
        if ($test_globals) { $xf = glb_cls(); }
    }

    $tc = $tc + (microtime(true)-$startc);
    echo "<br>Class time = " . (microtime(true)-$startc) . "\n\n";

    echo "<br>";
    echo "<br>Total Array time (so far) = " . $ta . "(100,000 iterations) \n\n";
    echo "<br>Total Class time (so far) = " . $tc . "(100,000 iterations) \n\n";
    echo "<br>";

}
echo "TOTAL TIMES:";
echo "<br>";
echo "<br>Total Array time = " . $ta . "(1,000,000 iterations) \n\n";
echo "<br>Total Class time = " . $tc . "(1,000,000 iterations)\n\n";


// test functions

function getArray($a,$b,$c,$d,$e,$f)
{
    $arr = array();
    $arr['a'] = $a;
    $arr['b'] = $b;
    $arr['c'] = $c;
    $arr['d'] = $d;
    $arr['d'] = $e;
    $arr['d'] = $f;
    return($arr);
}

//-------------------------------------

function setArrAtoB($r)
{
    $r['a'] = $r['b'];
}

//-------------------------------------

function glb_cls()
{
    global $xo;

    $xo->d = "ddxxdd";
    return ($xo->f);
}

//-------------------------------------

function glb_arr()
{
    global $xr;

    $xr['d'] = "ddxxdd";
    return ($xr['f']);
}

//-------------------------------------

?>

يقرأ الاختبار:1 مهام اختبار:1 اختبار Globals:1 وظائف الاختبار:1

وقت الصفيف = 1.58905816078 وقت الفصل = 1.11980104446 إجمالي وقت الصفيف (حتى الآن) = 1.58903813362 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 1.11979603767 (100،000 تكرار)

وقت الصفيف = 1.02581000328 وقت الفصل = 1.22492313385 إجمالي وقت الصفيف (حتى الآن) = 2.61484408379 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 2.34471416473 (100،000 تكرار)

وقت الصفيف = 1.29942297935 وقت الفصل = 1.18844485283 إجمالي وقت الصفيف (حتى الآن) = 3.91425895691 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 3.5331492424 (100،000 تكرار)

وقت الصفيف = 1.28776097298 وقت الفصل = 1.02383089066 إجمالي وقت الصفيف (حتى الآن) = 5.2020149231 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 4.55697512627 (100،000 تكرار)

وقت الصفيف = 1.312355999518 وقت الفصل = 1.38880181313 إجمالي وقت الصفيف (حتى الآن) = 6.51436591148 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 5.945777097893 (100،000 تكرار)

وقت الصفيف = 1.3007349968 وقت الفصل = 1.07644081116 إجمالي وقت الصفيف (حتى الآن) = 7.81509685516 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 7.022220678329 (100،000 تكرار)

وقت الصفيف = 1.12752890587 وقت الفصل = 1.07106018066 إجمالي وقت الصفيف (حتى الآن) = 8.94262075424 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 8.09326195717 (100،000 تكرار)

وقت الصفيف = 1.088901999661 وقت الفصل = 1.09139609337 وقت الصفيف (حتى الآن) = 10.0315177441 (100،000 تكرار) وقت الفصل الدراسي (حتى الآن) = 9.18465089798 (100،000 تكرار)

وقت الصفيف = 1.6172170639 وقت الفصل = 1.14714384079 إجمالي وقت الصفيف (حتى الآن) = 11.6487307549 (100000 تكرار) إجمالي وقت الفصل (حتى الآن) = 10.3317887783 (100،000 تكرار)

وقت الصفيف = 1.53738498688 وقت الفصل = 1.28127002716 إجمالي وقت الصفيف (حتى الآن) = 13.1861097813 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 11.6130547523 (100،000 تكرار)

إجمالي الأوقات:إجمالي وقت الصفيف = 13.1861097813 (1،000،000 تكرار) وقت الفصل الإجمالي = 11.6130547523 (1،000،000 تكرار)

لذا، في كلتا الحالتين، الفرق لا يكاد يذكر.لقد تفاجأت جدًا عندما وجدت أنه بمجرد البدء في الوصول إلى الأشياء عالميًا، تصبح الفصول الدراسية أسرع قليلاً.

لكن لا تثق بي، قم بتشغيله بنفسك.أنا شخصيًا أشعر الآن بعدم الشعور بالذنب تمامًا بشأن استخدام الفصول الدراسية في تطبيقاتي عالية الأداء.:د

@ ريتشارد فارنو

لقد قمت بتشغيل الكود الخاص بك بالضبط (بعد إصلاح الأخطاء الصغيرة)، وحصلت على نتائج مختلفة كثيرًا عنك.تم تشغيل الفصول كثيرًا عند تثبيت PHP 5.3.17.

وقت الصفيف = 0.69054913520813 وقت الفصل = 1.1762700080872

إجمالي وقت الصفيف (حتى الآن) = 0.69054508209229 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 1.1762590408325 (100،000 تكرار)

وقت الصفيف = 0.99001502990723 وقت الفصل = 1.22034907341

إجمالي وقت الصفيف (حتى الآن) = 1.680560588837 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 2.3966031074524 (100،000 تكرار)

وقت الصفيف = 0.99191808700562 وقت الفصل = 1.2245700359344

إجمالي وقت الصفيف (حتى الآن) = 2.6724660396576 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 3.621166945038 (100،000 تكرار)

وقت الصفيف = 0.9890251159668 وقت الفصل = 1.2246470451355

إجمالي وقت الصفيف (حتى الآن) = 3.661484003067 (100،000 تكرار) وقت الفصل الإجمالي (حتى الآن) = 4.8458080291748 (100،000 تكرار)

وقت الصفيف = 0.99573588371277 وقت الفصل = 1.1242771148682

إجمالي وقت الصفيف (حتى الآن) = 4.6572148799896 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 5.9700801372528 (100،000 تكرار)

وقت الصفيف = 0.88518786430359 وقت الفصل = 1.1427340507507

إجمالي وقت الصفيف (حتى الآن) = 5.5423986911774 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 7.1128082275391 (100،000 تكرار)

وقت الصفيف = 0.87605404853821 وقت الفئة = 0.95899105072021

إجمالي وقت الصفيف (حتى الآن) = 6.4184486865997 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 8.0717933177948 (100،000 تكرار)

وقت الصفيف = 0.73414516448975 وقت الفصل = 1.0223190784454

إجمالي وقت الصفيف (حتى الآن) = 7.15258888442993 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 9.0941033333342 (100،000 تكرار)

وقت الصفيف = 0.95230412483215 وقت الفصل = 1.059828042984

إجمالي وقت الصفيف (حتى الآن) = 8.1048839092255 (100،000 تكرار) إجمالي وقت الفصل (حتى الآن) = 10.153927326202 (100،000 تكرار)

وقت الصفيف = 0.75814390182495 وقت الفصل = 0.84455919265747

إجمالي وقت الصفيف (حتى الآن) = 8.8630249500275 (100000 تكرار) إجمالي وقت الفصل (حتى الآن) = 10.998482465744 (100،000 تكرار) إجمالي الأوقات:

إجمالي وقت الصفيف = 8.8630249500275 (1،000،000 تكرار) وقت الفصل الإجمالي = 10.998482465744 (1،000،000 تكرار)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top