Browse Source

Merge branch 'master' of https://github.com/kenjikobe/FrameworkBenchmarks into kenjikobe-master

Patrick Falls 12 years ago
parent
commit
70b6c88223

+ 45 - 0
php-phalcon-micro/README.md

@@ -0,0 +1,45 @@
+# Phalcon PHP Micro Benchmarking Test
+
+This is the Phalcon Micro PHP portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
+
+### JSON Encoding Test
+Uses the PHP standard [JSON encoder](http://www.php.net/manual/en/function.json-encode.php).
+
+* [JSON test controller](public/index.php)
+
+
+### Data-Store/Database Mapping Test
+Uses Phalcon\DB component
+
+* [DB test controller](public/index.php)
+
+### Template Test
+Uses Phalcon's template engine 'Volt'
+
+* [Template test controller](public/index.php)
+
+
+## Infrastructure Software Versions
+The tests were run with:
+
+* [Phalcon 1.0.0](http://phalconphp.com/)
+* [PHP Version 5.4.13](http://www.php.net/) with FPM, APC and Phalcon extension
+* [nginx 1.4.0](http://nginx.org/)
+* [MySQL 5.5.29](https://dev.mysql.com/)
+
+## Test URLs
+### JSON Encoding Test
+
+http://localhost/json
+
+### Data-Store/Database Mapping Test
+
+http://localhost/db
+
+### Variable Query Test
+
+http://localhost/db?queries=2
+
+### Templating Test
+
+http://localhost/fortunes

+ 0 - 0
php-phalcon-micro/__init__.py


+ 14 - 0
php-phalcon-micro/benchmark_config

@@ -0,0 +1,14 @@
+{
+  "framework": "phalcon-micro",
+  "tests": [{
+    "default": {
+      "setup_file": "setup",
+      "json_url": "/json",
+      "db_url": "/db",
+      "query_url": "/db?queries=",
+      "fortune_url": "/fortunes",
+      "port": 8080,
+      "sort": 72
+    }
+  }]
+}

+ 0 - 0
php-phalcon-micro/compiled-templates/.keepit


+ 125 - 0
php-phalcon-micro/deploy/nginx.conf

@@ -0,0 +1,125 @@
+#user  nobody;
+worker_processes  8;
+
+#error_log  logs/error.log;
+#error_log  logs/error.log  notice;
+#error_log  logs/error.log  info;
+
+#pid        logs/nginx.pid;
+
+
+events {
+    worker_connections  1024;
+}
+
+
+http {
+    include       /usr/local/nginx/conf/mime.types;
+    default_type  application/octet-stream;
+
+    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
+    #                  '$status $body_bytes_sent "$http_referer" '
+    #                  '"$http_user_agent" "$http_x_forwarded_for"';
+
+    #access_log  logs/access.log  main;
+
+    sendfile        on;
+    #tcp_nopush     on;
+
+    #keepalive_timeout  0;
+    keepalive_timeout  65;
+
+    #gzip  on;
+
+    server {
+        listen       8080;
+        server_name  localhost;
+
+        #charset koi8-r;
+
+        #access_log  logs/host.access.log  main;
+
+        #location / {
+        #    root   html;
+        #    index  index.html index.htm;
+        #}
+
+        #error_page  404              /404.html;
+
+        # redirect server error pages to the static page /50x.html
+        #
+        #error_page   500 502 503 504  /50x.html;
+        #location = /50x.html {
+        #    root   html;
+        #}
+
+        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
+        #
+        #location ~ \.php$ {
+        #    proxy_pass   http://127.0.0.1;
+        #}
+
+        root /home/ubuntu/FrameworkBenchmarks/php-phalcon-micro/public/;
+        index  index.php;
+
+        location / {
+            try_files $uri $uri/ /index.php?_url=$uri&$args;
+        }
+
+        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
+        #
+        location ~ \.php$ {
+            try_files $uri =404;
+            fastcgi_pass   127.0.0.1:9001;
+            fastcgi_index  index.php;
+#            fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
+            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
+            include        /usr/local/nginx/conf/fastcgi_params;
+        }
+
+        # deny access to .htaccess files, if Apache's document root
+        # concurs with nginx's one
+        #
+        #location ~ /\.ht {
+        #    deny  all;
+        #}
+    }
+
+
+    # another virtual host using mix of IP-, name-, and port-based configuration
+    #
+    #server {
+    #    listen       8000;
+    #    listen       somename:8080;
+    #    server_name  somename  alias  another.alias;
+
+    #    location / {
+    #        root   html;
+    #        index  index.html index.htm;
+    #    }
+    #}
+
+
+    # HTTPS server
+    #
+    #server {
+    #    listen       443;
+    #    server_name  localhost;
+
+    #    ssl                  on;
+    #    ssl_certificate      cert.pem;
+    #    ssl_certificate_key  cert.key;
+
+    #    ssl_session_timeout  5m;
+
+    #    ssl_protocols  SSLv2 SSLv3 TLSv1;
+    #    ssl_ciphers  HIGH:!aNULL:!MD5;
+    #    ssl_prefer_server_ciphers   on;
+
+    #    location / {
+    #        root   html;
+    #        index  index.html index.htm;
+    #    }
+    #}
+
+}

+ 9 - 0
php-phalcon-micro/deploy/php-phalcon-micro

@@ -0,0 +1,9 @@
+<VirtualHost *:8080>
+  Alias /php-phalcon/ "/home/ubuntu/FrameworkBenchmarks/php-phalcon-micro/public/"
+  <Directory /home/ubuntu/FrameworkBenchmarks/php-phalcon-micro/public/>
+          Options Indexes FollowSymLinks MultiViews
+          #AllowOverride None
+          Order allow,deny
+          allow from all
+  </Directory>
+</VirtualHost>

+ 100 - 0
php-phalcon-micro/public/index.php

@@ -0,0 +1,100 @@
+<?php
+
+try {
+
+    $app = new Phalcon\Mvc\Micro();
+
+    // Setting up the database connection
+    $app['db'] = function() {
+
+        return new \Phalcon\Db\Adapter\Pdo\Mysql(array(
+            'dsn'       => 'host=localhost;dbname=hello_world;charset=utf8',
+            'username'   => 'benchmarkdbuser',
+            'password'   => 'benchmarkdbpass',
+            'persistent' => true
+        ));
+    };
+
+    // Setting up the view component (seems to be required even when not used)
+    $app['view'] = function() {
+
+        $view = new \Phalcon\Mvc\View();
+
+        $view->setViewsDir(__DIR__ . '/../views/');
+
+        $view->registerEngines(array(
+            ".volt" => function($view, $di) {
+
+                $volt = new \Phalcon\Mvc\View\Engine\Volt($view, $di);
+
+                $volt->setOptions(array(
+                    "compiledPath" => __DIR__ . "/../compiled-templates/",
+                    "compiledExtension" => ".c",
+                    "compiledSeparator" => '_',
+                ));
+
+                return $volt;
+            }
+        ));
+
+        return $view;
+    };
+
+    $app->map('/json', function() {
+        header("Content-Type: application/json");
+        echo json_encode('Hello World!');
+    });
+
+    //
+    $app->map('/db', function() use ($app) {
+
+        $db = $app['db'];
+
+        $queries = $app->request->getQuery('queries', null, 1);
+
+        $worlds = array();
+
+        for ($i = 0; $i < $queries; ++$i) {
+            $worlds[] = $db->fetchOne('SELECT * FROM world WHERE id = ' . mt_rand(1, 10000), Phalcon\Db::FETCH_ASSOC);
+        }
+
+        echo json_encode($worlds);
+    });
+
+    // /fortunes
+    $app->map('/fortunes', function() use ($app) {
+
+        $fortunes = $app['db']->query('SELECT * FROM fortune')->fetchAll();
+
+        $fortunes[] = array(
+            'id' => 0,
+            'message' => 'Additional fortune added at request time.'
+        );
+
+        usort($fortunes, function($left, $right) {
+            $l = $left['message'];
+            $r = $right['message'];
+            if ($l === $r) {
+                return 0;
+            } else {
+                if ($l > $r) {
+                    return 1;
+                } else {
+                    return -1;
+                }
+            }
+        });
+
+        header("Content-Type: text/html; charset=utf-8");
+
+        echo $app['view']->getRender('bench', 'fortunes', array(
+            'fortunes' => $fortunes
+        ));
+
+    });
+
+    $app->handle();
+
+} catch(\Phalcon\Exception $e) {
+    echo "PhalconException: ", $e->getMessage();
+}

+ 26 - 0
php-phalcon-micro/setup.py

@@ -0,0 +1,26 @@
+import subprocess
+import sys
+import setup_util
+from os.path import expanduser
+
+home = expanduser("~")
+
+def start(args):
+  setup_util.replace_text("php-phalcon-micro/public/index.php", "localhost", ""+ args.database_host +"")
+  setup_util.replace_text("php-phalcon-micro/deploy/nginx.conf", "root .*\/FrameworkBenchmarks", "root " + home + "/FrameworkBenchmarks")
+
+  try:
+    subprocess.check_call("sudo chown -R www-data:www-data php-phalcon", shell=True)
+    subprocess.check_call("sudo php-fpm --fpm-config config/php-fpm.conf -g " + home + "/FrameworkBenchmarks/php-phalcon-micro/deploy/php-fpm.pid", shell=True)
+    subprocess.check_call("sudo /usr/local/nginx/sbin/nginx -c " + home + "/FrameworkBenchmarks/php-phalcon-micro/deploy/nginx.conf", shell=True)
+    return 0
+  except subprocess.CalledProcessError:
+    return 1
+def stop():
+  try:
+    subprocess.call("sudo /usr/local/nginx/sbin/nginx -s stop", shell=True)
+    subprocess.call("sudo kill -QUIT $( cat php-phalcon/deploy/php-fpm.pid )", shell=True)
+    subprocess.check_call("sudo chown -R $USER:$USER php-phalcon-micro", shell=True)
+    return 0
+  except subprocess.CalledProcessError:
+    return 1

+ 1 - 0
php-phalcon-micro/views/bench/fortunes.volt

@@ -0,0 +1 @@
+<table><tr><th>id</th><th>message</th></tr>{% for fortune in fortunes %}<tr><td>{{ fortune['id'] }}</td><td>{{ fortune['message'] | e }}</td></tr>{% endfor %}</table>

+ 1 - 0
php-phalcon-micro/views/layouts/bench.volt

@@ -0,0 +1 @@
+<!DOCTYPE html><html><head><title>Fortunes</title><meta charset="utf-8"></head><body>{{ content() }}</body></html>

+ 3 - 4
php-phalcon/app/config/config.php

@@ -9,10 +9,9 @@ return new \Phalcon\Config(array(
         'name'     => 'hello_world',
     ),
     'application' => array(
-        'controllersDir' => __DIR__ . '/../../app/controllers/',
-        'modelsDir'      => __DIR__ . '/../../app/models/',
-        'viewsDir'       => __DIR__ . '/../../app/views/',
-        'routes'         => __DIR__ . '/../../app/config/routes.php',
+        'controllersDir' => APP_PATH . '/app/controllers/',
+        'modelsDir'      => APP_PATH . '/app/models/',
+        'viewsDir'       => APP_PATH . '/app/views/',
         'baseUri'        => '/',
     )
 ));

+ 1 - 1
php-phalcon/app/config/routes.php

@@ -1,6 +1,6 @@
 <?php
 
-$router = new Phalcon\Mvc\Router();
+$router = new Phalcon\Mvc\Router(false);
 
 $router->add('/json', array(
     'controller' => 'bench',

+ 20 - 27
php-phalcon/app/controllers/BenchController.php

@@ -1,11 +1,14 @@
 <?php
 
+use Phalcon\Mvc\View,
+    Phalcon\Mvc\Model\Resultset;
+
 class BenchController extends \Phalcon\Mvc\Controller
 {
     public function initialize()
     {
         // views must be renderd explicitly. safes processing time when not needed.
-        $this->view->disable();
+        $this->view->setRenderLevel(View::LEVEL_LAYOUT);
     }
 
     public function jsonAction() {
@@ -15,7 +18,9 @@ class BenchController extends \Phalcon\Mvc\Controller
     }
 
     public function dbAction() {
-        $queries = $this->getQueryOrDefault('queries', 1);
+
+        $queries = $this->request->getQuery('queries', null, 1);
+
         $worlds = array();
 
         for ($i = 0; $i < $queries; ++$i) {
@@ -26,50 +31,38 @@ class BenchController extends \Phalcon\Mvc\Controller
     }
 
     public function fortunesAction() {
+
         // since the resultset is immutable get an array instead
         // so we can add the new fortune
         $fortunes = Fortunes::find()->toArray();
+
         $fortunes[] = array(
             'id' => 0,
             'message' => 'Additional fortune added at request time.'
         );
 
         usort($fortunes, function($left, $right) {
-            if ($left['message'] === $right['message']) {
+            $l = $left['message'];
+            $r = $right['message'];
+            if ($l === $r) {
                 return 0;
-            } else if ($left['message'] > $right['message']) {
-                return 1;
             } else {
-                return -1;
+                if ($l > $r) {
+                    return 1;
+                } else {
+                    return -1;
+                }
             }
         });
 
-        return $this->sendContentAsText(
-            $this->view->getRender('bench', 'fortunes', array(
-                'fortunes' => $fortunes
-            ))
-        );
-    }
+        $this->response->setHeader("Content-Type", "text/html; charset=utf-8");
 
-    private function getQueryOrDefault($query, $default) {
-        return $this->request->getQuery($query) !== null
-            ? $this->request->getQuery($query)
-            : $default;
-    }
-
-    private function sendContentAsText($content) {
-        $response = new Phalcon\Http\Response();
-        $response->setStatusCode(200, "OK");
-        $response->setHeader("Content-Type", "text/html; charset=utf-8");
-        $response->setContent($content);
-        return $response;
+        $this->view->fortunes = $fortunes;
     }
 
     private function sendContentAsJson($content) {
-        $response = new Phalcon\Http\Response();
-        $response->setStatusCode(200, "OK");
+        $response = new Phalcon\Http\Response(json_encode($content));
         $response->setHeader("Content-Type", "application/json");
-        $response->setContent(json_encode($content));
         return $response;
     }
 }

+ 0 - 1
php-phalcon/app/models/Fortunes.php

@@ -1,6 +1,5 @@
 <?php
 
-
 class Fortunes extends \Phalcon\Mvc\Model
 {
     public $id;

+ 0 - 1
php-phalcon/app/models/Worlds.php

@@ -1,6 +1,5 @@
 <?php
 
-
 class Worlds extends \Phalcon\Mvc\Model
 {
     public $id;

+ 1 - 20
php-phalcon/app/views/bench/fortunes.volt

@@ -1,20 +1 @@
-{% extends "templates/base.volt" %}
-
-{% block title %} Fortunes {% endblock %}
-
-{% block content %}
-    <table>
-        <tr>
-            <th>id</th>
-            <th>message</th>
-        </tr>
-
-        {% for fortune in fortunes %}
-            <tr>
-                <td>{{ fortune['id'] }}</td>
-                <td>{{ fortune['message'] | e }}</td>
-            </tr>
-        {% endfor %}
-
-    </table>
-{% endblock %}
+<table><tr><th>id</th><th>message</th></tr>{% for fortune in fortunes %}<tr><td>{{ fortune['id'] }}</td><td>{{ fortune['message'] | e }}</td></tr>{% endfor %}</table>

+ 1 - 0
php-phalcon/app/views/layouts/bench.volt

@@ -0,0 +1 @@
+<!DOCTYPE html><html><head><title>Fortunes</title><meta charset="utf-8"></head><body>{{ content() }}</body></html>

+ 0 - 10
php-phalcon/app/views/templates/base.volt

@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <title>{% block title %}{% endblock %}</title>
-    <meta charset="utf-8">
-</head>
-<body>
-{% block content %}{% endblock %}
-</body>
-</html>

+ 0 - 6
php-phalcon/public/.htaccess

@@ -1,6 +0,0 @@
-<IfModule mod_rewrite.c>
-    RewriteEngine On
-    RewriteCond %{REQUEST_FILENAME} !-d
-    RewriteCond %{REQUEST_FILENAME} !-f
-    RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]
-</IfModule>

+ 37 - 19
php-phalcon/public/index.php

@@ -1,8 +1,11 @@
 <?php
 
+define('APP_PATH', realpath('..'));
+
 try {
+
     // Load the config
-    $config = include(__DIR__."/../app/config/config.php");
+    $config = include APP_PATH . "/app/config/config.php";
 
     // Register an autoloader
     $loader = new \Phalcon\Loader();
@@ -15,27 +18,39 @@ try {
     $di = new Phalcon\DI\FactoryDefault();
 
     // Setting up the router
-    $di->set('router', function() use ($config) {
-        return include($config->application->routes);
-    });
+    $di->set('router', require APP_PATH . '/app/config/routes.php');
 
-    //Register Volt as a service
-    $di->set('voltService', function($view, $di) {
-        $volt = new \Phalcon\Mvc\View\Engine\Volt($view, $di);
-        $volt->setOptions(array(
-            "compiledPath" => "../app/compiled-templates/",
-            "compiledExtension" => ".compiled"
-        ));
-
-        return $volt;
+    //MetaData
+    $di->set('modelsMetadata', function(){
+        if (function_exists('apc_store')) {
+            return new Phalcon\Mvc\Model\MetaData\Apc();
+        } else {
+            return new Phalcon\Mvc\Model\MetaData\Files(array(
+                'metaDataDir' => APP_PATH . "/app/compiled-templates/"
+            ));
+        }
     });
 
     // Setting up the view component (seems to be required even when not used)
     $di->set('view', function() use ($config) {
+
         $view = new \Phalcon\Mvc\View();
+
         $view->setViewsDir($config->application->viewsDir);
+
         $view->registerEngines(array(
-            ".volt" => 'voltService'
+            ".volt" => function($view, $di) {
+
+                $volt = new \Phalcon\Mvc\View\Engine\Volt($view, $di);
+
+                $volt->setOptions(array(
+                    "compiledPath" => APP_PATH . "/app/compiled-templates/",
+                    "compiledExtension" => ".compiled",
+                    "compiledSeparator" => '_',
+                ));
+
+                return $volt;
+            }
         ));
 
         return $view;
@@ -43,11 +58,14 @@ try {
 
     // Setting up the database connection
     $di->set('db', function() use ($config) {
+
+        $database = $config->database;
+
         return new \Phalcon\Db\Adapter\Pdo\Mysql(array(
-            'host'     => $config->database->host,
-            'username' => $config->database->username,
-            'password' => $config->database->password,
-            'dbname'   => $config->database->name,
+            'host' => $database->host,
+            'username' => $database->username,
+            'password' => $database->password,
+            'dbname' => $database->name,
             'options'  => array(
                 PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
             )
@@ -61,4 +79,4 @@ try {
 
 } catch(\Phalcon\Exception $e) {
     echo "PhalconException: ", $e->getMessage();
-}
+}