Skip to content

Commit 0bfe0de

Browse files
committed
A bunch of new updates
1 parent ff187ba commit 0bfe0de

114 files changed

Lines changed: 11062 additions & 16 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

benchpress.php

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,49 @@
11
<?php
2-
/**
3-
* Plugin Name: BenchPress
4-
* Description: A tool for benchmarking PHP code snippets and WordPress queries to help developers optimize performance.
5-
* Version: 1.1
6-
* Author: Your Name
7-
* Text Domain: benchpress
8-
* License: GPL-2.0+
9-
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
10-
*/
112

12-
// Exit if accessed directly
13-
if ( ! defined( 'ABSPATH' ) ) {
14-
exit;
3+
/**
4+
* The plugin bootstrap file
5+
*
6+
* @link https://robertdevore.com
7+
* @since 1.0.0
8+
* @package Back_In_Stock_Notifications
9+
*
10+
* @wordpress-plugin
11+
*
12+
* Plugin Name: BenchPress
13+
* Description: A tool for benchmarking PHP code snippets and WordPress® queries to help developers optimize performance.
14+
* Plugin URI: https://github.com/robertdevore/benchpress/
15+
* Version: 1.0.0
16+
* Author: Robert DeVore
17+
* Author URI: https://robertdevore.com/
18+
* License: GPL-2.0+
19+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
20+
* Text Domain: benchpress
21+
* Domain Path: /languages
22+
* Update URI: https://github.com/robertdevore/benchpress/
23+
*/
24+
25+
// If this file is called directly, abort.
26+
if ( ! defined( 'WPINC' ) ) {
27+
die;
1528
}
1629

1730
// Define constants.
1831
define( 'BENCHPRESS_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
1932
define( 'BENCHPRESS_VERSION', '1.0.0' );
2033

34+
// Add the Plugin Update Checker.
35+
require 'vendor/plugin-update-checker/plugin-update-checker.php';
36+
use YahnisElsts\PluginUpdateChecker\v5\PucFactory;
37+
38+
$myUpdateChecker = PucFactory::buildUpdateChecker(
39+
'https://github.com/robertdevore/benchpress/',
40+
__FILE__,
41+
'benchpress'
42+
);
43+
44+
// Set the branch that contains the stable release.
45+
$myUpdateChecker->setBranch( 'main' );
46+
2147
/**
2248
* Summary of benchpress_create_snapshots_table
2349
*
@@ -162,6 +188,7 @@ function benchpress_render_settings_page() {
162188
update_option( 'benchpress_tax_terms', sanitize_text_field( $_POST['benchpress_tax_terms'] ) );
163189
update_option( 'benchpress_orderby', sanitize_text_field( $_POST['benchpress_orderby'] ) );
164190
update_option( 'benchpress_order', in_array( $_POST['benchpress_order'], ['ASC', 'DESC'] ) ? $_POST['benchpress_order'] : 'ASC' );
191+
update_option( 'benchpress_enable_transient_vs_query', isset( $_POST['benchpress_enable_transient_vs_query'] ) ? 1 : 0 );
165192
}
166193

167194
// Retrieve saved settings.
@@ -198,6 +225,9 @@ function benchpress_render_settings_page() {
198225
echo '<td><input type="number" name="benchpress_loop_count" value="' . esc_attr( $loop_count ) . '" /></td></tr>';
199226
echo '<tr><th>' . esc_html__( 'Enable Switch vs Match Benchmark', 'benchpress' ) . '</th>';
200227
echo '<td><input type="checkbox" name="benchpress_enable_switch_vs_match" ' . checked( 1, $enable_switch_vs_match, false ) . ' /></td></tr>';
228+
echo '<tr><th>' . esc_html__( 'Enable Transient vs Direct Query Benchmark', 'benchpress' ) . '</th>';
229+
echo '<td><input type="checkbox" name="benchpress_enable_transient_vs_query" ' . checked( 1, get_option( 'benchpress_enable_transient_vs_query', 1 ), false ) . ' /></td></tr>';
230+
201231
echo '</table>';
202232

203233
// WP_Query Customization Section.
@@ -465,17 +495,17 @@ function benchpress_download_snapshots() {
465495
wp_die( esc_html__( 'No snapshots available to download.', 'benchpress' ) );
466496
}
467497

468-
// Set headers to initiate a file download.
498+
// Set headers to initiate file download.
469499
header( 'Content-Type: text/csv; charset=utf-8' );
470-
header( 'Content-Disposition: attachment; filename=snapshots.csv' );
500+
header( 'Content-Disposition: attachment; filename=' . sanitize_title( get_bloginfo( 'name' ) ) . '-benchpress-' . date( 'Y-m-d_H-i-s' ) . '.csv' );
471501

472-
// Open output stream for writing CSV data.
502+
// Open output stream for CSV.
473503
$output = fopen( 'php://output', 'w' );
474504

475505
// Add CSV headers.
476506
fputcsv( $output, [ 'ID', 'Date', 'Benchmark Name', 'Execution Time', 'Description' ] );
477507

478-
// Populate CSV with snapshot data.
508+
// Loop through each snapshot and format data.
479509
foreach ( $snapshots as $snapshot ) {
480510
$snapshot_data = json_decode( $snapshot['snapshot_data'], true );
481511
foreach ( $snapshot_data as $benchmark ) {

includes/helper-functions.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,66 @@ function benchpress_run_all_benchmarks() {
247247
$benchmarks[] = $switch_vs_match;
248248
}
249249

250+
// Run Transient vs Direct Query Benchmark only if enabled.
251+
if ( get_option( 'benchpress_enable_transient_vs_query', 1 ) ) {
252+
$benchmarks[] = benchpress_benchmark_transient_vs_direct_query();
253+
}
254+
250255
$benchmarks[] = benchpress_benchmark_wp_query_by_id();
251256
$benchmarks[] = benchpress_benchmark_array_merge();
252257
$benchmarks[] = benchpress_benchmark_string_concatenation();
253258

259+
// Return the benchmarks array directly
254260
return $benchmarks;
255261
}
262+
263+
/**
264+
* Benchmark Transient Caching vs. Direct Database Queries.
265+
*
266+
* @since 1.1.0
267+
* @return array Benchmark data showing performance difference between transient caching and direct database querying.
268+
*/
269+
function benchpress_benchmark_transient_vs_direct_query() {
270+
// Retrieve settings
271+
$loop_count = get_option( 'benchpress_loop_count', 10 );
272+
$post_type = get_option( 'benchpress_post_type', 'post' );
273+
global $wpdb;
274+
275+
// Build dynamic query.
276+
$query = $wpdb->prepare(
277+
"SELECT * FROM {$wpdb->posts} WHERE post_type = %s LIMIT %d",
278+
$post_type,
279+
$loop_count
280+
);
281+
282+
// Measure execution time for direct query.
283+
$start_direct = microtime( true );
284+
$wpdb->get_results( $query );
285+
$end_direct = microtime( true );
286+
$direct_query_time = $end_direct - $start_direct;
287+
288+
// Measure execution time for transient caching.
289+
$start_transient = microtime( true );
290+
$cache_key = 'benchpress_transient_query';
291+
$results = get_transient( $cache_key );
292+
293+
if ( false === $results ) {
294+
$results = $wpdb->get_results( $query );
295+
set_transient( $cache_key, $results, HOUR_IN_SECONDS );
296+
}
297+
$end_transient = microtime( true );
298+
$transient_time = $end_transient - $start_transient;
299+
300+
$difference = $direct_query_time - $transient_time;
301+
$faster_or_slower = $difference > 0 ? 'slower' : 'faster';
302+
303+
return [
304+
'name' => esc_html__( 'Transient Caching vs Direct Query', 'benchpress' ),
305+
'execution_time'=> round( abs( $difference ), 5 ),
306+
'description' => sprintf(
307+
esc_html__( 'Direct query is %s by %s seconds compared to transient caching.', 'benchpress' ),
308+
$faster_or_slower,
309+
round( abs( $difference ), 5 )
310+
),
311+
];
312+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace YahnisElsts\PluginUpdateChecker\v5;
4+
5+
if ( !class_exists(PucFactory::class, false) ):
6+
7+
class PucFactory extends \YahnisElsts\PluginUpdateChecker\v5p4\PucFactory {
8+
}
9+
10+
endif;
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
namespace YahnisElsts\PluginUpdateChecker\v5p4;
4+
5+
if ( !class_exists(Autoloader::class, false) ):
6+
7+
class Autoloader {
8+
const DEFAULT_NS_PREFIX = 'YahnisElsts\\PluginUpdateChecker\\';
9+
10+
private $prefix;
11+
private $rootDir;
12+
private $libraryDir;
13+
14+
private $staticMap;
15+
16+
public function __construct() {
17+
$this->rootDir = dirname(__FILE__) . '/';
18+
19+
$namespaceWithSlash = __NAMESPACE__ . '\\';
20+
$this->prefix = $namespaceWithSlash;
21+
22+
$this->libraryDir = $this->rootDir . '../..';
23+
if ( !self::isPhar() ) {
24+
$this->libraryDir = realpath($this->libraryDir);
25+
}
26+
$this->libraryDir = $this->libraryDir . '/';
27+
28+
//Usually, dependencies like Parsedown are in the global namespace,
29+
//but if someone adds a custom namespace to the entire library, they
30+
//will be in the same namespace as this class.
31+
$isCustomNamespace = (
32+
substr($namespaceWithSlash, 0, strlen(self::DEFAULT_NS_PREFIX)) !== self::DEFAULT_NS_PREFIX
33+
);
34+
$libraryPrefix = $isCustomNamespace ? $namespaceWithSlash : '';
35+
36+
$this->staticMap = array(
37+
$libraryPrefix . 'PucReadmeParser' => 'vendor/PucReadmeParser.php',
38+
$libraryPrefix . 'Parsedown' => 'vendor/Parsedown.php',
39+
);
40+
41+
//Add the generic, major-version-only factory class to the static map.
42+
$versionSeparatorPos = strrpos(__NAMESPACE__, '\\v');
43+
if ( $versionSeparatorPos !== false ) {
44+
$versionSegment = substr(__NAMESPACE__, $versionSeparatorPos + 1);
45+
$pointPos = strpos($versionSegment, 'p');
46+
if ( ($pointPos !== false) && ($pointPos > 1) ) {
47+
$majorVersionSegment = substr($versionSegment, 0, $pointPos);
48+
$majorVersionNs = __NAMESPACE__ . '\\' . $majorVersionSegment;
49+
$this->staticMap[$majorVersionNs . '\\PucFactory'] =
50+
'Puc/' . $majorVersionSegment . '/Factory.php';
51+
}
52+
}
53+
54+
spl_autoload_register(array($this, 'autoload'));
55+
}
56+
57+
/**
58+
* Determine if this file is running as part of a Phar archive.
59+
*
60+
* @return bool
61+
*/
62+
private static function isPhar() {
63+
//Check if the current file path starts with "phar://".
64+
static $pharProtocol = 'phar://';
65+
return (substr(__FILE__, 0, strlen($pharProtocol)) === $pharProtocol);
66+
}
67+
68+
public function autoload($className) {
69+
if ( isset($this->staticMap[$className]) && file_exists($this->libraryDir . $this->staticMap[$className]) ) {
70+
include($this->libraryDir . $this->staticMap[$className]);
71+
return;
72+
}
73+
74+
if ( strpos($className, $this->prefix) === 0 ) {
75+
$path = substr($className, strlen($this->prefix));
76+
$path = str_replace(array('_', '\\'), '/', $path);
77+
$path = $this->rootDir . $path . '.php';
78+
79+
if ( file_exists($path) ) {
80+
include $path;
81+
}
82+
}
83+
}
84+
}
85+
86+
endif;

0 commit comments

Comments
 (0)