【问题标题】:CodeIgniter Performance load view multiple times vs loop in viewCodeIgniter 性能多次加载视图与视图中的循环
【发布时间】:2013-01-19 09:18:36
【问题描述】:

我正在尝试解决可能的扩展性能问题。这两种情况是否有更明显的性能优势:

场景一:

多次调用以加载视图并每次传递少量数据

控制器

public function index()
{
    $this->load->view('header');
    $this->load->view('table_head');
    $results = $this->db->select('*')->from('table')->get()->result_array();
    foreach ($results as $key)
    {
        $this->load->view('table_row', $key);
    }
    $this->load->view('table_foot');
    $this->load->view('footer');
}

查看表头

<table>
    <thead>
        <tr>
            <th>...</th>
            <th>...</th>
            ...
        </tr>
    </thead>
    <tbody>

查看 table_row

        <tr>
            <td><?php echo $var_a; ?></td>
            <td><?php echo $var_b; ?></td>
            ...
        </tr>

查看桌脚

    </tbody>
    <tfoot>
        <tr>
            <td>...</td>
            <td>...</td>
            ...
        </tr>
    </tfoot>
</table>

场景 2:

进行 1 次调用以加载视图并传递大量数据

控制器

public function index()
{
    $this->load->view('header');
    $this->data['results'] = $this->db->select('*')->from('table')->get()->result_array();
    $this->load->view('table', $this->data);
    $this->load->view('footer');
}

查看表格

...
<table>
    <thead>Header Info...</thead>
    <tbody>
        <?php foreach ($results as $key): ?>
            <tr>echo row information as needed</tr>
        <?php endforeach; ?>
    </tbody>
<table>
...

我一直在使用场景 1,因为它有助于保持我的应用程序模块化,并通过在控制器中保持逻辑循环来保持 MVC 格式。但是如果说 SQL 调用的结果是 1000 个条目,甚至更多,这两种场景之间是否存在明显的性能差异?我是否试图让我的应用程序过于模块化?我确实尝试尽可能多地回收我的代码,因此我的更多方法将至少加载 8 个视图。

【问题讨论】:

    标签: php performance codeigniter templates variable-assignment


    【解决方案1】:

    好吧,我崩溃并编写了一个小脚本来为我的表充气以进行这些测试。这是我的小测试的结果。为了保持测试等效,我只更改了我正在显示的视图。

    场景 1

    控制器:

    public function results()
    {
        $this->load->view('headers/header', $this->default_lib->viewdata());
        $this->load->view('body_bits/bodyopen');
        $this->title['title'] = 'Testing Tesults';
        $this->title['link'] = 'tests';
        $this->title['link_text'] = 'Back to Tests';
        $this->load->view('body_bits/page_title', $this->title);
        $this->load->view('tests/results_open');
    
        $results = $this->db->select('*')->
            from('test_results')->
            where('software', 'nwralpha')->
            order_by('time', 'ASC')->
            //limit('10')->
            get()->result_array();
        foreach ($results as $key)
        {
            $this->data['name'] = ucwords($this->ion_auth->user($key['user_id'])->row()->username);
            $this->data['time_taken'] = $key['time'];
            $this->data['test_taken'] = $key['test_type'];
            $this->data['common'] = ($key['common_codes'] == 1) ? 'Common Code List' : 'Full Code List';
            $this->data['date'] = $key['date'];
    
            $this->load->view('tests/results', $this->data);
        }
    
        $this->load->view('tests/results_close');
        $this->load->view('body_bits/bodyclose');
        $this->load->view('footers/footer');
    }
    

    查看

    <tr>
        <td><?php echo $name; ?></td>
        <td><?php echo $time_taken; ?></td>
        <td><?php echo $test_taken; ?></td>
        <td><?php echo $common; ?></td>
        <td><?php echo $date; ?></td>
    </tr>
    

    场景 2

    控制器:

    public function results()
    {
        $this->load->view('headers/header', $this->default_lib->viewdata());
        $this->load->view('body_bits/bodyopen');
        $this->title['title'] = 'Testing Tesults';
        $this->title['link'] = 'tests';
        $this->title['link_text'] = 'Back to Tests';
        $this->load->view('body_bits/page_title', $this->title);
        $this->load->view('tests/results_open');
    
        $results = $this->db->select('*')->
            from('test_results')->
            where('software', 'nwralpha')->
            order_by('time', 'ASC')->
            //limit('10')->
            get()->result_array();
    
        $this->data['results'] = $results;
        $this->load->view('tests/resultsloop', $this->data);
    
        $this->load->view('tests/results_close');
        $this->load->view('body_bits/bodyclose');
        $this->load->view('footers/footer');
    }
    

    查看

    <?php foreach ($results as $key): ?>
    <tr>
        <td><?php echo ucwords($this->ion_auth->user($key['user_id'])->row()->username); ?></td>
        <td><?php echo $key['time']; ?></td>
        <td><?php echo $key['test_type']; ?></td>
        <td><?php echo $key['common_codes']; ?></td>
        <td><?php echo $key['date']; ?></td>
    </tr>
    <?php endforeach; ?>
    

    结果

    我用 1004 个结果和 11004 个结果测试了这两个示例,这是我使用 CodeIgniter 内置的 Profiler 发现的结果

    1004 个结果

    场景 1 平均加载时间:1.94462 秒
    场景2平均加载时间:1.1723秒

    11004 个结果

    场景 1 平均加载时间:19.78867 秒
    场景2平均加载时间:11.81502秒

    这是什么意思

    对于只想知道答案而不是阅读整篇文章的其他人:
    虽然逻辑和 HTML 的分离是 MVC 框架的重点,但在某些可接受的情况下,您可以使用逻辑来确定如何显示信息。在这种情况下,我只使用了一个循环来根据需要不断吐出统一的信息。该测试表明,进行最少的视图调用更有效。

    【讨论】:

    • 不错!我从没想过应用场景 1,在这篇文章之后也永远不会。
    【解决方案2】:

    恕我直言,控制器将相关资产移交给正确的视图。 例如,如果您没有得到任何结果——“无结果”条件的操作过程——应该发生在控制器中。 (而不是检查 $results 是否存在于您的视图中)

    逻辑——我们如何显示结果? -- 发生在视图中。控制器传递 $results,然后视图负责如何显示这些结果。在场景 #1 中,您必须进入控制器,以更改页面设计。

    当 $results 太大时......然后使用分页。

    【讨论】:

    • 对此仅作几点说明,如果$results 返回为空,它将永远不会进入foreach 循环,因此控制器已经在执行所有结果选项的逻辑。我知道我可以选择(几乎是要求)进行分页,但考虑到用户是否希望一次查看大量数据,哪种方案效果更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多