类与2D数组

时间:2020-03-05 18:42:23  来源:igfitidea点击:

在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会对性能产生什么影响,尽管我怀疑在这里实例化对象的成本可能更高,即使只是一点点。

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

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

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

回答

通常,我遵循以下规则:

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

2)如果要在应用程序的一部分中使用它来快速处理数据,请使其成为2D数组。

回答

It's the speed that I am thinking of mostly, for anything more complex than what I have here I'd probably go with classes but the question is, what is the cost of a class?

这似乎是过早的优化。应用程序不会对现实世界造成任何影响,但是使用类可以使我们使用getter和setter方法,并且通常会更好地进行代码封装和代码重用。

使用数组会增加难以阅读和维护代码的成本,因此我们无法轻松地对代码进行单元测试,并且具有良好的类结构,其他开发人员应该更容易理解它们是否需要使用它。

而且以后需要添加其他方法来操纵这些方法时,就没有架构可以扩展。

回答

就OO而言,我们拥有的类不是真正的类,它只是构造为占用实例变量的空间。

就是说,在示例中,速度可能不是很多问题,但这仅仅是样式问题。

有趣的是,如果我们将对象构造为一个真正的"人物"类,并考虑该人物类可能需要的其他属性和动作,那么我们不仅会注意到样式性能编写代码,而且还会注意到速度性能。

回答

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

回答

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.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次迭代)

因此,无论哪种方式,差异都可以忽略不计。我非常惊讶地发现,一旦我们开始全局访问事物,类实际上就会变得更快一些。

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