在 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 方法,并且通常更有利于代码封装和代码重用。

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

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

从面向对象的角度来看,您拥有的类不是真正的类 - 它只是被构造为占用实例变量的空间。

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

有趣的是,如果您将对象构造为真正的“人”类,并考虑您可能想要的人类的其他属性和操作,那么您不仅会注意到编写代码的风格表现,而且还会注意到还可以提高性能。

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

Teifion,如果您仅使用类来替代数组,那么您离 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个测试全球:1个测试功能:1

阵列时间= 1.58905816078班级时间= 1.11980104446总阵列时间(到目前为止)= 1.58903813362(100,000迭代)总班级时间(到目前为止)= 1.11979603767(100,000迭代)

阵列时间= 1.02581000328班级时间= 1.224923133385总阵列时间(到目前为止)= 2.61484408379(100,000迭代)总课程时间(到目前为止)= 2.34471416473(100,000迭代)

阵列时间= 1.29942297935班级时间= 1.188444485283总阵列时间(到目前为止)= 3.91425895691(100,000迭代)总班级时间(到目前为止)= 3.53331492424(100,000迭代)

阵列时间= 1.28776097298班级时间= 1.02383089066总阵列时间(到目前为止)= 5.2020149231(100,000迭代)总课程时间(到目前为止)= 4.55697512627(100,000迭代)

阵列时间= 1.31235599518班级时间= 1.38880181313总阵列时间(到目前为止)= 6.51436591148(100,000迭代)(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迭代)(100,000迭代)总课程时间(到目前为止)= 9.18465089798(100,000迭代)

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

@理查德瓦尔诺

我运行了你的确切代码(修复了小错误后),得到的结果与你有很大不同。类在我的 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.09410333333342(100,000迭代)

阵列时间= 0.95230412483215班级时间= 1.059828042984

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

阵列时间= 0.75814390182495班级时间= 0.84445919265747

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

总阵列时间= 8.8630249500275(1,000,000迭代)总班级时间= 10.998482465744(1,000,000迭代)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top