Tuurlijk

Execute Positioned String Insertion

Jan 20th, 2014
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 28.31 KB | None | 0 0
  1. <?php
  2. error_reporting(E_ALL & ~E_NOTICE);
  3. /*****************************************************************************
  4.  *  Copyright notice
  5.  *
  6.  *  ⓒ 2013 Michiel Roos <michiel@maxserv.nl>
  7.  *  All rights reserved
  8.  *
  9.  *  This script is part of the TYPO3 project. The TYPO3 project is free
  10.  *  software; you can redistribute it and/or modify it under the terms of the
  11.  *  GNU General Public License as published by the Free Software Foundation;
  12.  *  either version 2 of the License, or (at your option) any later version.
  13.  *
  14.  *  The GNU General Public License can be found at
  15.  *  http://www.gnu.org/copyleft/gpl.html.
  16.  *
  17.  *  This script is distributed in the hope that it will be useful, but
  18.  *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  19.  *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  20.  *  more details.
  21.  *
  22.  *  This copyright notice MUST APPEAR in all copies of the script!
  23.  ****************************************************************************/
  24.  
  25. /*****************************************************************************
  26.  *                    Tiny TYPO3 Test Suite v 1.0.0
  27.  *                           by: Michiel Roos
  28.  *                          _______
  29.  *                         /_  __(_)___  __  __
  30.  *                          / / / / __ \/ / / /
  31.  *                         / / / / / / / /_/ /
  32.  *                        /_/ /_/_/ /_/\__, /
  33.  *                                  /____/
  34.  *                   ________  ______  ____ _____
  35.  *                  /_  __/\ \/ / __ \/ __ \__  /
  36.  *                   / /    \  / /_/ / / / //_ <
  37.  *                  / /     / / ____/ /_/ /__/ /
  38.  *                 /_/     /_/_/    \____/____/
  39.  *             ______          __     _____       _ __
  40.  *            /_  __/__  _____/ /_   / ___/__  __(_) /____
  41.  *             / / / _ \/ ___/ __/   \__ \/ / / / / __/ _ \
  42.  *            / / /  __(__  ) /_    ___/ / /_/ / / /_/  __/
  43.  *           /_/  \___/____/\__/   /____/\__,_/_/\__/\___/
  44.  *
  45.  *           https://github.com/Tuurlijk/TinyTypo3TestSuite
  46.  *
  47.  ****************************************************************************/
  48.  
  49. /*****************************************************************************
  50.  * Setup
  51.  *
  52.  * - testname: Displayed in the page title and page header
  53.  * - runs    : The default number of runs
  54.  * - skipSets: An array of setNames to skip
  55.  ****************************************************************************/
  56. $testName = '\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::executePositionedStringInsertion()';
  57. $runs = 100;
  58. $skipSets = array();
  59.  
  60. /*****************************************************************************
  61.  * Parameter Sets
  62.  *
  63.  * Define multiple parameter sets here so you can excersise the method well.
  64.  * Each method needs a description. The other parameters must match the
  65.  * parameter names of the method.
  66.  ****************************************************************************/
  67. $parameterSets = array(
  68.     'set1' => array (
  69.         'description' => 'Insert before field_c',
  70.         'list' => 'field_a, field_b;;;;2-2-2, field_c;;;;3-3-3',
  71.         'insertionList' => 'field_b, field_d, field_c;;;4-4-4',
  72.         'insertionPosition' => 'before:field_c',
  73.     ),
  74.     'set2' => array (
  75.         'description' => 'Insert after field_a',
  76.         'list' => 'field_a, field_b;;;;2-2-2, field_c;;;;3-3-3',
  77.         'insertionList' => 'field_b, field_d, field_c;;;4-4-4',
  78.         'insertionPosition' => 'after:field_a',
  79.     ),
  80.     'set3' => array (
  81.         'description' => 'Empty position (append)',
  82.         'list' => 'field_a, field_b;;;;2-2-2, field_c;;;;3-3-3',
  83.         'insertionList' => 'field_b, field_d, field_c;;;4-4-4',
  84.         'insertionPosition' => '',
  85.     ),
  86.     'set4' => array (
  87.         'description' => 'Replace field_b',
  88.         'list' => 'field_a, field_b;;;;2-2-2, field_c;;;;3-3-3',
  89.         'insertionList' => 'field_b, field_d, field_c;;;4-4-4',
  90.         'insertionPosition' => 'replace:field_b',
  91.     )
  92. );
  93.  
  94. /*****************************************************************************
  95.  * Test Methods:
  96.  *
  97.  * Define your test methods here. Name them version1 - version[n].
  98.  * version1 must be the baseline implementation.
  99.  ****************************************************************************/
  100.  
  101. $descriptions['version1'] = 'Baseline';
  102. function version1($list, $insertionList, $insertionPosition = '') {
  103.         $list = trim($list);
  104.         $insertionList = removeDuplicatesForInsertion($insertionList, $list);
  105.         if ($insertionList) {
  106.             // Append data to the end (default):
  107.             if ($insertionPosition === '') {
  108.                 $list .= ($list ? ', ' : '') . $insertionList;
  109.             } else {
  110.                 $positions = trimExplode(',', $insertionPosition, TRUE);
  111.                 $items = explodeItemList($list);
  112.                 $isInserted = FALSE;
  113.                 // Iterate through all fields an check whether it's possible to inserte there:
  114.                 foreach ($items as $item => &$itemDetails) {
  115.                     $needles = getInsertionNeedles($item, $itemDetails['details']);
  116.                     // Insert data before:
  117.                     foreach ($needles['before'] as $needle) {
  118.                         if (in_array($needle, $positions)) {
  119.                             $itemDetails['rawData'] = $insertionList . ', ' . $itemDetails['rawData'];
  120.                             $isInserted = TRUE;
  121.                             break;
  122.                         }
  123.                     }
  124.                     // Insert data after:
  125.                     foreach ($needles['after'] as $needle) {
  126.                         if (in_array($needle, $positions)) {
  127.                             $itemDetails['rawData'] .= ', ' . $insertionList;
  128.                             $isInserted = TRUE;
  129.                             break;
  130.                         }
  131.                     }
  132.                     // Replace with data:
  133.                     foreach ($needles['replace'] as $needle) {
  134.                         if (in_array($needle, $positions)) {
  135.                             $itemDetails['rawData'] = $insertionList;
  136.                             $isInserted = TRUE;
  137.                             break;
  138.                         }
  139.                     }
  140.                     // Break if insertion was already done:
  141.                     if ($isInserted) {
  142.                         break;
  143.                     }
  144.                 }
  145.                 // If insertion point could not be determined, append the data:
  146.                 if (!$isInserted) {
  147.                     $list .= ($list ? ', ' : '') . $insertionList;
  148.                 } else {
  149.                     $list = generateItemList($items, TRUE);
  150.                 }
  151.             }
  152.         }
  153.         return $list;
  154. }
  155.  
  156. $descriptions['version2'] = 'Optimized baseline';
  157. function version2($list, $insertionList, $insertionPosition = '') {
  158.         $list = $newList = trim($list, ', \\t\\n\\r\\0\\x0B');
  159.         if ($insertionList === '') {
  160.             return $list;
  161.         }
  162.         if ($list === '') {
  163.             return $insertionList;
  164.         }
  165.  
  166.         $insertionList = removeDuplicatesForInsertion($insertionList, $list);
  167.  
  168.         if ($insertionPosition === '') {
  169.             return $list . ',' . $insertionList;
  170.         }
  171.  
  172.         list($positionLocation, $positionName) = trimExplode(':', $insertionPosition);
  173.         // The $insertPosition may be a palette: after:--palette--;;title
  174.         // In the $list the palette may contain a LLL string in between the ;;
  175.         // Adjust the regex to match that
  176.         if (strpos($positionName, ';;') !== false) {
  177.             $positionName = str_replace(';;', ';[^;]*;', $positionName);
  178.         }
  179.  
  180.         $pattern = ('/(^|,\s*)(' . $positionName . '[^,$]*)/');
  181.         switch($positionLocation) {
  182.             case 'after':
  183.                 $newList = preg_replace($pattern, '$1$2, ' . $insertionList, $list);
  184.                 break;
  185.             case 'before':
  186.                 $newList = preg_replace($pattern, '$1' . $insertionList . ', $2', $list);
  187.                 break;
  188.             case 'replace':
  189.                 $newList = preg_replace($pattern, '$1' . $insertionList, $list);
  190.                 break;
  191.             default:
  192.         }
  193.  
  194.         // When the regexes did not replace anything; append the $insertionList
  195.         if ($list === $newList) {
  196.             return $list . ', ' . $insertionList;
  197.         }
  198.         return $newList;
  199. }
  200.  
  201. $descriptions['version3'] = 'Optimized baseline using better removeDuplicates';
  202. function version3($list, $insertionList, $insertionPosition = '') {
  203.         $list = $newList = trim($list, ', \\t\\n\\r\\0\\x0B');
  204.         if ($insertionList === '') {
  205.             return $list;
  206.         }
  207.         if ($list === '') {
  208.             return $insertionList;
  209.         }
  210.  
  211.         $insertionList = removeDuplicatesForInsertionOptimized($insertionList, $list);
  212.  
  213.         if ($insertionPosition === '') {
  214.             return $list . ',' . $insertionList;
  215.         }
  216.  
  217.         list($positionLocation, $positionName) = trimExplode(':', $insertionPosition);
  218.         // The $insertPosition may be a palette: after:--palette--;;title
  219.         // In the $list the palette may contain a LLL string in between the ;;
  220.         // Adjust the regex to match that
  221.         if (strpos($positionName, ';;') !== false) {
  222.             $positionName = str_replace(';;', ';[^;]*;', $positionName);
  223.         }
  224.  
  225.         $pattern = ('/(^|,\s*)(' . $positionName . '[^,$]*)/');
  226.         switch($positionLocation) {
  227.             case 'after':
  228.                 $newList = preg_replace($pattern, '$1$2, ' . $insertionList, $list);
  229.                 break;
  230.             case 'before':
  231.                 $newList = preg_replace($pattern, '$1' . $insertionList . ', $2', $list);
  232.                 break;
  233.             case 'replace':
  234.                 $newList = preg_replace($pattern, '$1' . $insertionList, $list);
  235.                 break;
  236.             default:
  237.         }
  238.  
  239.         // When the regexes did not replace anything; append the $insertionList
  240.         if ($list === $newList) {
  241.             return $list . ', ' . $insertionList;
  242.         }
  243.         return $newList;
  244. }
  245.  
  246. /*****************************************************************************
  247.  * Helper Methods:
  248.  *
  249.  * Add any methods that are needed by any of the test methods here.
  250.  ****************************************************************************/
  251.  
  252. function explodeItemList($itemList) {
  253.         $items = array();
  254.         $itemParts = trimExplode(',', $itemList, TRUE);
  255.         foreach ($itemParts as $itemPart) {
  256.             $itemDetails = trimExplode(';', $itemPart, FALSE, 5);
  257.             $key = $itemDetails[0];
  258.             if (strstr($key, '--')) {
  259.                 // If $key is a separator (--div--) or palette (--palette--) then it will be appended by a unique number. This must be removed again when using this value!
  260.                 $key .= count($items);
  261.             }
  262.             if (!isset($items[$key])) {
  263.                 $items[$key] = array(
  264.                     'rawData' => $itemPart,
  265.                     'details' => array(
  266.                         'field' => $itemDetails[0],
  267.                         'label' => $itemDetails[1],
  268.                         'palette' => $itemDetails[2],
  269.                         'special' => $itemDetails[3],
  270.                         'styles' => $itemDetails[4]
  271.                     )
  272.                 );
  273.             }
  274.         }
  275.         return $items;
  276. }
  277.  
  278. function generateItemList(array $items, $useRawData = FALSE) {
  279.         $itemParts = array();
  280.         foreach ($items as $item => $itemDetails) {
  281.             if (strstr($item, '--')) {
  282.                 // If $item is a separator (--div--) or palette (--palette--) then it may have been appended by a unique number. This must be stripped away here.
  283.                 $item = preg_replace('/[0-9]+$/', '', $item);
  284.             }
  285.             if ($useRawData) {
  286.                 $itemParts[] = $itemDetails['rawData'];
  287.             } else {
  288.                 $itemParts[] = count($itemDetails['details']) > 1 ? implode(';', $itemDetails['details']) : $item;
  289.             }
  290.         }
  291.         return implode(', ', $itemParts);
  292. }
  293.  
  294. function getInsertionNeedles($item, array $itemDetails) {
  295.         if (strstr($item, '--')) {
  296.             // If $item is a separator (--div--) or palette (--palette--) then it may have been appended by a unique number. This must be stripped away here.
  297.             $item = preg_replace('/[0-9]+$/', '', $item);
  298.         }
  299.         $needles = array(
  300.             'before' => array($item, 'before:' . $item),
  301.             'after' => array('after:' . $item),
  302.             'replace' => array('replace:' . $item)
  303.         );
  304.         if ($itemDetails['palette']) {
  305.             $palette = $item . ';;' . $itemDetails['palette'];
  306.             $needles['before'][] = $palette;
  307.             $needles['before'][] = 'before:' . $palette;
  308.             $needles['after'][] = 'after:' . $palette;
  309.             $needles['replace'][] = 'replace:' . $palette;
  310.         }
  311.         return $needles;
  312. }
  313.  
  314. function removeDuplicatesForInsertion($insertionList, $list = '') {
  315.         $pattern = '/(?:^|,)\\s*\\b([^;,]+)\\b[^,]*/';
  316.         $listItems = array();
  317.         if ($list && preg_match_all($pattern, $list, $listMatches)) {
  318.             $listItems = $listMatches[1];
  319.         }
  320.         if ($insertionList && preg_match_all($pattern, $insertionList, $insertionListMatches)) {
  321.             $insertionItems = array();
  322.             $insertionDuplicates = FALSE;
  323.             foreach ($insertionListMatches[1] as $insertionIndex => $insertionItem) {
  324.                 if (!isset($insertionItems[$insertionItem]) && !in_array($insertionItem, $listItems)) {
  325.                     $insertionItems[$insertionItem] = TRUE;
  326.                 } else {
  327.                     unset($insertionListMatches[0][$insertionIndex]);
  328.                     $insertionDuplicates = TRUE;
  329.                 }
  330.             }
  331.             if ($insertionDuplicates) {
  332.                 $insertionList = implode('', $insertionListMatches[0]);
  333.             }
  334.         }
  335.         return $insertionList;
  336. }
  337.  
  338. function removeDuplicatesForInsertionOptimized($insertionList, $list = '') {
  339.         if ($list === '') {
  340.             return $insertionList;
  341.         }
  342.         // Get a list of fieldNames that are present in the list.
  343.         preg_match_all('/(?:^|,)\\s*\\b([^;,]+)\\b[^,]*/', $list, $listMatches);
  344.         // Remove the field names form the insertionlist.
  345.         $fieldReplacePatterns = array();
  346.         foreach ($listMatches[1] as $fieldName) {
  347.             $fieldReplacePatterns[] = '/(?:^|,)\\s*\\b' . $fieldName . '\\b[^,$]*/';
  348.         }
  349.         return preg_replace($fieldReplacePatterns, '', $insertionList);
  350. }
  351.  
  352. function trimExplode($delim, $string, $removeEmptyValues = FALSE, $limit = 0) {
  353.         $explodedValues = explode($delim, $string);
  354.         $result = array_map('trim', $explodedValues);
  355.         if ($removeEmptyValues) {
  356.             $temp = array();
  357.             foreach ($result as $value) {
  358.                 if ($value !== '') {
  359.                     $temp[] = $value;
  360.                 }
  361.             }
  362.             $result = $temp;
  363.         }
  364.         if ($limit != 0) {
  365.             if ($limit < 0) {
  366.                 $result = array_slice($result, 0, $limit);
  367.             } elseif (count($result) > $limit) {
  368.                 $lastElements = array_slice($result, $limit - 1);
  369.                 $result = array_slice($result, 0, $limit - 1);
  370.                 $result[] = implode($delim, $lastElements);
  371.             }
  372.         }
  373.         return $result;
  374. }
  375.  
  376. /*****************************************************************************
  377.  * System (look, but don't touch ;-) . . . only touch if you must.
  378.  ****************************************************************************/
  379. $v = '1.0.0';
  380. $reverseExecutionOrder = 0;
  381. if (isset($_GET['source']) && $_GET['source']) {
  382.     show_source(__FILE__);
  383.     exit;
  384. }
  385. if (isset($_GET['runs'])) $runs = preg_replace('/[^0-9]/', '', $_GET['runs']);
  386. if (isset($_GET['reverseExecutionOrder'])) $reverseExecutionOrder = intval($_GET['reverseExecutionOrder']);
  387.  
  388. // Prepare
  389. $baselineTimes = $functionsToCall = $times = array();
  390. $allFunctions = get_defined_functions();
  391. $functions = array_filter($allFunctions['user'], create_function('$a','return strpos($a, "version") === 0;'));
  392. if ($reverseExecutionOrder) arsort($functions);
  393. foreach ($functions as $function) {
  394.     $xAxis[] = $function;
  395.     $functionsToCall[$function] = new ReflectionFunction($function);
  396. }
  397.  
  398. // Execute
  399. foreach ($parameterSets as $setName => $parameters) {
  400.     if (in_array($setName, $skipSets)) continue;
  401.     // Description is used later on, so clone the parameters
  402.     $functionParameters = $parameters;
  403.     unset($functionParameters['description']);
  404.     for ($i = 0; $i < $runs; $i++) {
  405.         foreach ($functions as $function) {
  406.             $start = microtime(TRUE);
  407.             $result = $functionsToCall[$function]->invokeArgs($functionParameters);
  408.             $time = microtime(TRUE) - $start;
  409.             if ($function === 'version1') {
  410.                 $baselineTimes[$setName] += $time * 1000;
  411.             }
  412.             if (is_array($result)) {
  413.                 $resultObjects[$setName][$function] = array_slice($result, 0, 20, TRUE);
  414.             } else {
  415.                 $resultObjects[$setName][$function] = $result;
  416.             }
  417.             $times[$setName][$function] += $time * 1000;
  418.         }
  419.     }
  420. }
  421.  
  422. function findFastestTimes($times) {
  423.     $fastestTimes = array();
  424.     foreach ($times as $setName => $timeData) {
  425.         foreach ($timeData as $functionName => $time) {
  426.             if (isset($fastestTimes[$functionName])) {
  427.                 $fastestTimes['overall'][$functionName] += $time;
  428.                 $fastestTimes[$setName][$functionName] += $time;
  429.             } else {
  430.                 $fastestTimes['overall'][$functionName] = $time;
  431.                 $fastestTimes[$setName][$functionName] = $time;
  432.             }
  433.         }
  434.     }
  435.     $fastestTimes = array_filter($fastestTimes, 'asort');
  436.     return $fastestTimes;
  437. }
  438.  
  439. function findWinner($times) {
  440.     $averagedTimes = array();
  441.     foreach ($times as $timeData) {
  442.         foreach ($timeData as $functionName => $time) {
  443.             $averagedTimes[$functionName] += $time;
  444.         }
  445.     }
  446.     asort($averagedTimes);
  447.     return $averagedTimes;
  448. }
  449.  
  450. $averagedTimes = findWinner($times);
  451. $fastestTimes = findFastestTimes($times);
  452.  
  453. /**
  454.  * Format an integer as a time value
  455.  *
  456.  * @param integer $time The value to format
  457.  *
  458.  * @return string
  459.  */
  460. function printSeconds($time) {
  461.     $prefix = '';
  462.     $suffix = 'μs';
  463.     if ($time < 0) {
  464.         $time = abs($time);
  465.         $prefix = '-';
  466.     }
  467.     if ($time === 0) {
  468.         $suffix = '';
  469.     }
  470.     if ($time >= 1000) {
  471.         $time = $time / 1000;
  472.         $suffix = 'ms';
  473.     }
  474.     if ($time >= 1000) {
  475.         $time = $time / 1000;
  476.         $suffix = ' s';
  477.     }
  478.     if ($time >= 60 && $suffix === ' s') {
  479.         $time = $time / 60;
  480.         $suffix = 'min!';
  481.     }
  482.     return $prefix . sprintf("%.2f {$suffix}", $time);
  483. }
  484.  
  485. ?>
  486. <html>
  487. <head>
  488.     <title><?php  echo $testName ?> | Tiny TYPO3 Test Suite v<?php echo $v ?></title>
  489.     <link rel="stylesheet" href="http://wiki.typo3.org/wiki/load.php?debug=false&amp;lang=en&amp;modules=mediawiki.legacy.commonPrint%2Cshared%7Cskins.typo3vector&amp;only=styles&amp;skin=typo3vector&amp;*" />
  490.     <style type="text/css">
  491.         h3 {
  492.             border-bottom: 1px solid #dedede;
  493.         }
  494.         h4 {
  495.             font-family: Share;
  496.             font-weight: normal;
  497.         }
  498.     </style>
  499.     <script src="http://code.jquery.com/jquery-2.0.3.min.js" type="text/javascript"></script>
  500.     <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js" type="text/javascript"></script>
  501.     <script src="http://code.highcharts.com/highcharts.js" type="text/javascript"></script>
  502.     <script src="http://code.highcharts.com/modules/exporting.js" type="text/javascript"></script>
  503. </head>
  504. <body>
  505. <div id="content" class="mw-body">
  506.     <h1 id="top"><?php echo $testName ?></h1>
  507.     <form action="<?php echo $_SERVER['SCRIPT_NAME'] ?>">
  508.         <label for="runs">Run the tests how many times?</label>
  509.         <input name="runs" id="runs" value="<?php echo $runs ?>"/>
  510.         <label for="runs"><a href="#help">Reverse execution order?</a></label>
  511.         <input type="checkbox" name="reverseExecutionOrder" id="reverseExecutionOrder" value="1" <?php echo ($reverseExecutionOrder) ? 'checked="checked"' : '' ?>/>
  512.         <input class="submit" type="submit" value="Go!"/>
  513.     </form>
  514.     <div class="timeAveraged" style="float: left;">
  515.         <p>Winner using averaged times over all sets: <strong><?php
  516.             $winner = array_slice($averagedTimes, 0, 1);
  517.             echo key($winner) ?></strong> <?php echo printSeconds(current($winner) / count($times)) ?>.</p>
  518.     <?php
  519.         if (count($parameterSets) > 1) {
  520.             echo '<ul>';
  521.             foreach ($averagedTimes as $function => $time) {
  522.                 echo '<li><b>' . $function . '</b>: ',
  523.                     ' ' . printSeconds($time / count($times)) . '</li>';
  524.             }
  525.             echo '</ul>';
  526.         }
  527.     ?>
  528.     </div>
  529.     <div class="timeFastest" style="margin-left: 50%;">
  530.         <p>The fastest function in any set is <strong><?php
  531.             $winner = array_slice($fastestTimes['overall'], 0, 1);
  532.             echo key($winner) ?></strong> <?php echo printSeconds(current($winner)) ?>.</p>
  533.     <?php
  534.         if (count($parameterSets) > 1) {
  535.             echo '<ul>';
  536.             foreach ($fastestTimes as $set => $functions) {
  537.                 if ($set !== 'overall') {
  538.                     echo '<li><b>' . $set . '</b>: ';
  539.                     $setWinner = array_slice($functions, 0, 1);
  540.                     echo key($setWinner) . ' ' . printSeconds(current($setWinner)) . '</li>';
  541.                 }
  542.             }
  543.             echo '</ul>';
  544.         }
  545.     ?>
  546.     </div>
  547.     <div id="resultGraph" style="min-width: 310px; min-height: 400px; margin: 0 auto"></div>
  548.     <h2>Parameter Sets</h2>
  549.     <?php
  550.         foreach ($times as $setName => $functionData) {
  551.             echo '<h3>' , ucfirst($setName) , '</h3>',
  552.                 '<p>' , $parameterSets[$setName]['description'] , '</p>',
  553.                 '<ul>';
  554.             foreach ($functionData as $function => $time) {
  555.                 $identifier = $setName . '-' . $function;
  556.                 echo '<li><a style="text-decoration: none" href="#', $identifier, '">',
  557.                     ucfirst($function),
  558.                     '</a> ',
  559.                     ': ',
  560.                     sprintf('<span style="min-width: 33px; display: inline-block; text-align: right; font-weight: bold;">%1.2d%%</span> ', $time * 100 / $baselineTimes[$setName]),
  561.                     sprintf('<span style="min-width: 50px; display: inline-block; text-align: right; margin: 0 10px;">%s</span> ', printSeconds($time)),
  562.                     $descriptions[$function],
  563.                     '</li>';
  564.             }
  565.             echo '</ul><h4>Parameters</h4><ul>';
  566.             foreach ($parameterSets[$setName] as $key => $value) {
  567.                 if ($key !== 'description') {
  568.                     if (is_array($value)) {
  569.                         echo '<li>' , $key , ':', '</li>'; var_dump($value);
  570.                     } else {
  571.                         echo '<li>' . $key . ' = ' . (string) $value . '</li>';
  572.                     }
  573.                 } else {
  574.                     $setDescriptions[] = $value;
  575.                 }
  576.             }
  577.             echo '</ul>';
  578.         }
  579.     ?>
  580.     <script>
  581.         /**
  582.          * Format an integer as a time value
  583.          *
  584.          * @param {String} time The value to format in microseconds.
  585.          * @param {Number} decimals The amount of decimals
  586.          *
  587.          * @return string
  588.          */
  589.         function printSeconds(time, decimals) {
  590.            decimals = typeof decimals !== 'undefined' ? decimals : 2;
  591.             var prefix = '',
  592.                 suffix = 'μs';
  593.             if (time < 0) {
  594.                 time = Math.abs(time);
  595.                 prefix = '-';
  596.             }
  597.             if (time == 0) {
  598.                 suffix = '';
  599.             }
  600.             if (time >= 1000) {
  601.                 time = time / 1000;
  602.                 suffix = 'ms';
  603.             }
  604.             if (time >= 1000) {
  605.                 time = time / 1000;
  606.                 suffix = ' s';
  607.             }
  608.             if (time >= 60 && suffix == ' s') {
  609.                 time = time / 60;
  610.                 suffix = 'min!';
  611.             }
  612.             return prefix + Highcharts.numberFormat(time, decimals) + ' ' + suffix;
  613.         }
  614.  
  615.         var baseLineTimes = [<?php echo implode(',', $baselineTimes) ?>];
  616.         var descriptions = ['<?php echo implode("','", array_map('addslashes', $descriptions)) ?>'];
  617.         var setDescriptions = ['<?php echo implode("','", array_map('addslashes', $setDescriptions)) ?>'];
  618.         jQuery(document).ready(function($) {
  619.             $('#resultGraph').highcharts({
  620.                 chart: {
  621.                     zoomType: 'y'
  622.                 },
  623.                 title: {
  624.                     text: '<?php echo $testName ?>'
  625.                 },
  626.                 xAxis: {
  627.                     categories: ['<?php echo implode("','", $xAxis)  ?>'],
  628.                     title: {
  629.                         text: null
  630.                     }
  631.                 },
  632.                 yAxis: {
  633.                     min: 0,
  634.                     title: {
  635.                         text: 'Time (milliseconds)',
  636.                         align: 'high'
  637.                     },
  638.                     labels: {
  639.                         overflow: 'justify',
  640.                         formatter: function() {
  641.                             return printSeconds(this.value);
  642.                         }
  643.                     }
  644.                 },
  645.                 tooltip: {
  646.                     useHTML: true,
  647.                     formatter: function() {
  648.                         return '<strong><a style="text-decoration: none" href="#' + this.point.series.name + '-' + this.point.category + '">' + this.point.series.name + ', ' + descriptions[this.point.x] + '</a></strong><br/>' +
  649.                             setDescriptions[this.series.index] + '<br/>' +
  650.                             printSeconds(this.point.y) +
  651.                             ' (' + Math.ceil(this.point.y * 100 / baseLineTimes[this.point.series.index]) + '%)';
  652.                     }
  653.                 },
  654.                 legend: {
  655.                     enabled: true
  656.                 },
  657.                 credits: {
  658.                     enabled: false
  659.                 },
  660.                 series: [
  661.                     <?php
  662.                     foreach ($times as $setName => $setTimes) {
  663.                         $series[] = "{
  664.                             name: '" . $setName . "',
  665.                             data: [" . implode(',', $setTimes) . "]
  666.                         }";
  667.                     }
  668.                     echo implode(',', $series);
  669.                     ?>
  670.                 ]
  671.             });
  672.             $('#showSourceLink').on('click', function(e) {
  673.                 e.preventDefault();
  674.                 $.ajax({
  675.                     url: '<?php echo $_SERVER['SCRIPT_NAME'] ?>?source=1',
  676.                     cache: false
  677.                 })
  678.                 .done(function(html) {
  679.                     $('.loading').hide();
  680.                     $('#sourceCode').html(html);
  681.                     $('html, body').animate({
  682.                         scrollTop: $("#source").offset().top
  683.                     }, {
  684.                         duration: 2000,
  685.                         easing: 'easeOutBounce'
  686.                     });
  687.                 });
  688.             });
  689.             $('.top').on('click', function(e) {
  690.                 e.preventDefault();
  691.                 $('html, body').animate({
  692.                     scrollTop: $("#top").offset().top
  693.                 }, {
  694.                     duration: 2000,
  695.                     easing: 'easeOutBounce'
  696.                 });
  697.             });
  698.         });
  699.     </script>
  700.     <h2>Data results</h2>
  701.     <?php
  702.         foreach ($times as $setName => $functionData) {
  703.             echo '<h3>' . ucfirst($setName) . '</h3>';
  704.             echo '<p>' . $parameterSets[$setName]['description'] . '</p>';
  705.             echo '<ul>';
  706.             foreach ($parameterSets[$setName] as $key => $value) {
  707.                 if ($key !== 'description') {
  708.                     if (is_array($value)) {
  709.                         echo '<li>' , $key , ':', '</li>'; var_dump($value);
  710.                     } else {
  711.                         echo '<li>' . $key . ' = ' . (string) $value . '</li>';
  712.                     }
  713.                 }
  714.             }
  715.             echo '</ul>';
  716.             foreach ($functionData as $function => $time) {
  717.                 echo '<h4 id="', $setName . '-' . $function, '">', ucfirst($function), '</h4>',
  718.                     '<p>', $descriptions[$function], '</p>';
  719.                 var_dump($resultObjects[$setName][$function]);
  720.             }
  721.         }
  722.     ?>
  723.     <div id="p-personal" role="navigation" class="">
  724.         <ul>
  725.     <?php
  726.     foreach ($resultObjects as $setName => $functionData) {
  727.         foreach ($functionData as $function => $data) {
  728.             echo '<li><a href="#' . $setName . '-' . $function . '">' . ucfirst($setName) . ' - ' . ucfirst($function)  . '</a></h3>';
  729.         }
  730.     }
  731.     ?>
  732.             <li><a href="#about">About - v<?php echo $v ?></a></li>
  733.             <li><a href="#help">Help</a></li>
  734.             <li><a href="#source">Source Code</a></li>
  735.         </ul>
  736.     </div>
  737.     <div id="help">
  738.     <div id="about">
  739.         <h2>About</h2>
  740.         <p>Tiny TYPO3 Test Suite v<?php echo $v ?> is a script that helps you test different method implementations. Get the latest version from github:
  741.             <a href="https://github.com/Tuurlijk/TinyTypo3TestSuite">https://github.com/Tuurlijk/TinyTypo3TestSuite</a></p>
  742.     </div>
  743.         <h2>Help</h2>
  744.         <h3>Execution Order</h3>
  745.         <p>In some cases, the second function (non baseline) always runs faster than the baseline. Even when switching the code around. This toggle enables you to reverse the running order to check for this behaviour. Your winning function should still win whatever the execution order. If that is not the case, then this test has failed to determine what code runs faster.</p>
  746.     </div>
  747.     <div id="source">
  748.         <h2>Source Code</h2>
  749.         <pre id="sourceCode"><a href="#source" id="showSourceLink">Show the sourcecode of this file.</a></pre>
  750.     </div>
  751.     <a href="#top" class="top" style="position: fixed; bottom: 10px; left: 25px; text-decoration: none;">^ top</a>
  752.     <a href="https://github.com/Tuurlijk/TinyTypo3TestSuite"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"></a>
  753.     <div id="logo" style="position: absolute; top: 60px; left: 60px;"><img alt="" src="data:image/png;base64,
  754. iVBORw0KGgoAAAANSUhEUgAAAHYAAAAiCAYAAACKuC3wAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ
  755. bWFnZVJlYWR5ccllPAAABzJJREFUeNrsWwlsFUUYHh4VkEMEKaACHmAV0KTENFxaiIqK1sQDNYIS
  756. UTQRDSlH1DSIBqSgAQVijGIEjdYDREXEIEo4LSiKgFgUMKCAIK1KFQoUSv1++y/v7zCzZ1/bkP2T
  757. Lztv59jd+Wb+a/c1qKysVLGcftLAb8PKfNUQh8sYRxrkqUWGNpNweBhoI06XAiXALuBnoBBYgv77
  758. 4umvA2JBEtVlATcA13K5KVf3ADEbtPadcdju87rHgY+BURhnd0xDzUuagdAMHIYDg4HzDX3+1kll
  759. 6RjwuoOAnrje5Rjvn5iKFBGLCSYV+yxwu4eKtpFwIMT1aTHcCMyNqUgBsSB1NA75QGMffc6xnP89
  760. 1XY+Fv+SAKmP4DjNJ6kkzdGnwyns5Kn9OISxl3/FNKSAWODREP36Wc5/FWKsXTENqSG2W4h+11jO
  761. Lwo4zkFga0xDamxsGBt3PYVDUL96duMToBxo5HOc7zHGCUtda2B8iHtbAXzEjmBzseC+8Og3Asgw
  762. tD8TmAq04nCvMZ+juSsD9gLLOHzz40CeAdxGcwhczOORQ7qZnch1Ln3p+rdQuAlcAqQL/2Y58BZw
  763. 6H/TCIIogXBWiAnsC1IKDeHSh3zjfuQJjPG8pe5CYEeI+5oB5DIZY/jcFqA73Z6lTyfgFyarAqCY
  764. /FeuO5tCPJ++wgPAApc2GbwAurq0IXIeAo4a6jJpM7j03QYMoHtPhJw8kiEuE+tXFqZQG01j7aF4
  765. InNc2o4Wod/bglSTlPAEbgQ2iGuQhvkA6GXp14q1gCSVHM4iNkmO3AfM8vF8tNh+4gXpCO3i2Y6N
  766. LQo5cXdidzYyeMekCtf76L8Obbe41JOHfZEBss89hvoJXEcqco7UDi4qf7ijcIApHvedzjsvk1Ui
  767. JXFWC9M23dLvKdYMzuIgP6Uda5J07f6GAlcZxvhNVWUC2/J90yLpwmq9Qvg/3YjYNSGJTefskUny
  768. fPR/2aOe0o47DSgXbfYZ6mX4NFU8cF+GLhQVNOPyXN4FQaSEiXB8hZ7CVjtCdvRB8fsxtsuOHAHI
  769. JL2v3ZdJ3S8BirXzpAnmi9/ZROzKCOou15hxyFOf47DYpR+tvHdqwTmk3PU8l11LTtBI8XtKyOvs
  770. YLXsiK6Os4QfU8wq22uxXxfwHr4W5S5E7KYIWaMsqOM+Ll7mQUvdOJBfXkue/2RRztHCu2Eq+SZq
  771. oUZOUNmqOX5Semtee4VLHuAYl9uwmg2T6GmR4JAlihMzzrJrd7AjoIczi9lBqS3ZJOJrCu3GCns4
  772. VrTLj3gdObEttbpLRflHlzEqNFOQEeD6zUW5PMGFeREeaCB2bbaFXHLt71JV72QV3/RQQ/ybapGk
  773. 3csOzx3sbJF8CayNeI2GoqyHKvItmZd23CPKHQJcXy6e3Q6xyyOoY1fbBBLJqF/ANuNK/C6ug0RM
  774. ofAlKEEwSrO3k2rgGvLjgkNaXVvLzvba+e18XrsZL1RHViV48iu00CCo9MauHeJCbimwFCirwyzb
  775. ZM3p68HlNbywo0qmxd6SNBHlfz3GKdOyVCZpz3a8M4c65KyeK+x0YUI0ft0lM+NHpoPc9qr+ymKR
  776. tZFqc0INjN2PJ9mRtYYdZVPTusjdbssIvsee+HYmta/wjO92EhTS2VkQURUVgNy0ekzuZO33Bp6Y
  777. sELzR58NFYhzpPLr6o1Ve8cDT2gVL0QcmLIec/jDt/oo87XgfkYILXVAoJwdL8c5olBlTA3er+0F
  778. yUvsJxCeFjEs+TLvUkiXptnCVSBlhbK/b/Uj5HV2wjjjeeUexbh76gmxJzQbFuZznpaW8/Ss9BLg
  779. W0NdqZaF8nKEHLF9hqQnOCaqqjdrORzGjTCpzWe0dFcYyWaHhB6oqzq95E1RPqyqEvmFPGe2pIs8
  780. 38Jj/KaWfm5CWmemSr7o6J9m8GCXY7d9huJNNTAJuRhv72lG7P0h+vwhyq092sr6IN9e/yDKXRKW
  781. RhTjHY9qz0DqGyoWPSlxnkdbmcwIsimqqfuEJe6kt/kvRniQnSr5KiyW6mnC7i7tyOnMsPTzkiO6
  782. u24TsrXbQjwExWG3YnEciPk8Kd+I8tUu895LOFclKthHEDL9WJpwyRaVsYd7LKDXOQR9N8ZcVpPv
  783. hIdLacKBlnbDRHlpwGsMEOVtbjuWyKWVNjIAqZTgXxDzeIoc5vjSkekGW3uz5pjNNoxDb3CaGM53
  784. ZA17MkmS8LojEPUKDs95NDvGpBbEHFplooib6T0rpQPpw79XgVXApyqZ6qRs2BLDGIPY1FHflRzP
  785. Ejar5H+nyOl9zVf6D4Q9iRCojFeF/rkqfZs0mJIbMXeuQkka+l8UvcqkHDB9vWH6mnM9m0Cb0Gbs
  786. rKrnpqU8Tk5Xwu9dgThKllPKcDUHxOTC0+u6K2qZVPqP7UbGwRD9i0T/Uh/tK0T7qL7DMvaKSRVv
  787. VcmUIanqNWz2+rDjZLPVs7jtfpVMh/6pqjJP/Z1o5j8BBgADhL1q2hRfzwAAAABJRU5ErkJggg==" /></div>
  788. </div>
  789. </body>
  790. </html>
Add Comment
Please, Sign In to add comment