【问题标题】:Classes vs 2D arrays类与二维数组
【发布时间】:2010-09-06 15:37:51
【问题描述】:

在 PHP 中使用 2D 数组或类哪个更好?我已经举了一个例子来说明我的意思。

// 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;

假设没有人出来表明课程太慢,看起来课程赢了。

我不知道应该接受哪个答案,我刚刚对所有答案都投了赞成票。


我现在已经编写了两个几乎相同的页面,一个使用 2D 数组(在发布此问题之前编写),现在一个使用类,我必须说该类生成了更好的代码。我不知道会产生多少开销,但我怀疑它会与代码本身的改进相媲美。

感谢您帮助我成为更好的程序员。

【问题讨论】:

    标签: php arrays class


    【解决方案1】:

    您在上面构建的“类”是大多数人在其他语言中使用 struct 的对象。我不确定 PHP 对性能的影响是什么,但我怀疑在这里实例化对象的成本可能更高,即使只是一点点。

    话虽如此,如果成本相对较低,我认为管理对象会更容易一些。

    我只是根据标题和您的问题说以下内容,但是: 请记住,类也提供了方法和访问控制的优势。因此,如果您想确保人们不会将权重更改为负数,您可以将weight 字段设为私有并提供一些访问器方法,例如getWeight()setWeight()。在setWeight() 中,您可以进行一些值检查,如下所示:

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

    【讨论】:

      【解决方案2】:

      这完全取决于您所说的“更好”是什么意思。我会选择面向对象的方式(使用类),因为我发现它可以使代码更简洁(至少在我看来)。但是,我不确定该选项的速度惩罚可能是什么。

      【讨论】:

        【解决方案3】:

        一般来说,我遵循这个规则:

        1) 如果您的应用程序的多个部分使用该数据结构,则将其设为一个类。

        2) 如果您在应用程序的某个部分中使用它来快速处理数据,请将其设为二维数组。

        【讨论】:

          【解决方案4】:

          这是我主要考虑的速度,对于比我在这里更复杂的东西,我可能会选择课程,但问题是,课程的成本是多少?

          这似乎是过早的优化。无论哪种方式,您的应用程序都不会对实际性能造成任何影响,但是使用类可以让您使用 getter 和 setter 方法,并且通常会更好地进行代码封装和代码重用。

          使用数组会导致代码更难阅读和维护,因此您无法轻松地对代码进行单元测试,并且如果需要使用良好的类结构,其他开发人员应该会发现更容易理解.

          当您稍后需要添加其他方法来操作这些时,您将没有要扩展的架构。

          【讨论】:

            【解决方案5】:

            在 OO 术语中,您拥有的类不是真正的类 - 它只是被构造为占用实例变量的空间。

            也就是说 - 速度可能没有太大问题 - 在你的例子中它只是一种风格。

            有趣的一点——如果你将对象构造成一个真正的“人”类——并考虑你可能想要的人类的其他属性和动作——那么你会注意到不仅是一种风格表现——写作代码 - 还可以提高性能。

            【讨论】:

              【解决方案6】:

              如果您的代码使用了很多对这些属性(名称/身高/体重)进行操作的函数,那么使用类可能是一个不错的选择。

              【讨论】:

                【解决方案7】:

                Teifion,如果您将类仅用作数组的替代品,那么您与 OOP 相去甚远。 OOP的本质是对象具有知识和责任,可以实际做事并与其他类协作。您的对象只有知识,除了无所事事地存在之外不能做任何事情,但是它们似乎是持久性提供者(知道如何在数据库中存储/检索自己的对象)的良好候选者。

                也不用担心性能。 PHP 中的对象既快速又轻量级,而且性能总体上被高估了。作为一名程序员,使用正确的方法来节省您的时间要比在程序中使用一些晦涩难懂、难以调试和修复的代码节省微秒时间要便宜。

                【讨论】:

                  【解决方案8】:

                  大多数时间数组与类的测试只测试实例化它们。一旦你真正开始对他们做某事。

                  我是一个只使用数组的“纯粹主义者”,因为性能要好得多。我写了下面的代码来证明自己是为了证明不使用类的额外麻烦是合理的(即使它们对程序员来说更容易)

                  可以说我对结果感到非常惊讶!

                      <?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 测试全局变量: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.31235599518 上课时间 = 1.38880181313 总阵列时间(到目前为止)= 6.51436591148(100,000 次迭代) 总课程时间(到目前为止)= 5.94577097893(100,000 次迭代)

                  阵列时间 = 1.3007349968 上课时间 = 1.07644081116 总阵列时间(到目前为止)= 7.81509685516(100,000 次迭代) 总课程时间(到目前为止)= 7.02220678329(100,000 次迭代)

                  阵列时间 = 1.12752890587 上课时间 = 1.07106018066 总阵列时间(到目前为止)= 8.94262075424(100,000 次迭代) 总课程时间(到目前为止)= 8.09326195717(100,000 次迭代)

                  阵列时间 = 1.08890199661 上课时间 = 1.09139609337 总阵列时间(到目前为止)= 10.0315177441(100,000 次迭代) 总课程时间(到目前为止)= 9.18465089798(100,000 次迭代)

                  阵列时间 = 1.6172170639 上课时间 = 1.14714384079 总阵列时间(到目前为止)= 11.6487307549(100,000 次迭代) 总课程时间(到目前为止)= 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 次迭代)

                  因此,无论哪种方式,差异都可以忽略不计。我很惊讶地发现,一旦你开始在全局范围内访问东西,类实际上会变得更快。

                  但是不要相信我,为你自己运行它。我个人现在对在我的高性能应用程序中使用类完全感到内疚。 :D

                  【讨论】:

                    【解决方案9】:

                    @理查德·瓦诺

                    我运行了您的确切代码(在修复了小错误之后),得到的结果与您大不相同。类在我的 PHP 5.3.17 安装上运行很多。

                    阵列时间 = 0.69054913520813 上课时间=1.1762700080872

                    总阵列时间(到目前为止)= 0.69054508209229(100,000 次迭代) 总课程时间(到目前为止)= 1.1762590408325(100,000 次迭代)

                    阵列时间 = 0.99001502990723 上课时间 = 1.22034907341

                    总阵列时间(到目前为止)= 1.6805560588837(100,000 次迭代) 总课程时间(到目前为止)= 2.3966031074524(100,000 次迭代)

                    阵列时间 = 0.99191808700562 上课时间 = 1.2245700359344

                    总阵列时间(到目前为止)= 2.6724660396576(100,000 次迭代) 总课程时间(到目前为止)= 3.6211669445038(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.1525888442993(100,000 次迭代) 总课程时间(到目前为止)= 9.0941033363342(100,000 次迭代)

                    阵列时间 = 0.95230412483215 上课时间=1.059828042984

                    总阵列时间(到目前为止)= 8.1048839092255(100,000 次迭代) 总课程时间(到目前为止)= 10.153927326202(100,000 次迭代)

                    阵列时间 = 0.75814390182495 上课时间 = 0.84455919265747

                    总阵列时间(到目前为止)= 8.8630249500275(100,000 次迭代) 总课程时间(到目前为止)= 10.998482465744(100,000 次迭代) 总次数:

                    总阵列时间 = 8.8630249500275(1,000,000 次迭代) 总课时 = 10.998482465744(1,000,000 次迭代)

                    【讨论】:

                      猜你喜欢
                      • 2011-12-18
                      • 2014-04-29
                      • 1970-01-01
                      • 1970-01-01
                      • 2010-11-17
                      • 2013-05-19
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多