3v4l.org

run code in 300+ PHP versions simultaneously
<?php // All of the code needed for this test. function __( $text ) { return $text; } /** * Webfonts Schema Validator. * * Validates the webfont schema. */ class WP_Webfonts_Schema_Validator { /** * Valid font styles. * * @since 5.9.0 * * @var string[] */ const VALID_FONT_STYLE = array( 'normal', 'italic', 'oblique', 'inherit', 'initial', 'revert', 'unset' ); /** * Valid font display values. * * @since 5.9.0 * * @var string[] */ const VALID_FONT_DISPLAY = array( 'auto', 'block', 'fallback', 'swap' ); /** * Valid font weight values. * * @since 5.9.0 * * @var string[] */ const VALID_FONT_WEIGHT = array( 'normal', 'bold', 'bolder', 'lighter', 'inherit' ); /** * An array of valid CSS properties for @font-face. * * @since 5.9.0 * * @var string[] */ protected $font_face_properties = array( 'ascend-override', 'descend-override', 'font-display', 'font-family', 'font-stretch', 'font-style', 'font-weight', 'font-variant', 'font-feature-settings', 'font-variation-settings', 'line-gap-override', 'size-adjust', 'src', 'unicode-range', ); /** * Basic schema structure. * * @since 5.9.0 * * @var array */ protected $basic_schema = array( 'provider' => '', 'font-family' => '', 'font-style' => 'normal', 'font-weight' => '400', 'font-display' => 'fallback', ); /** * Webfont being validated. * * Set as a property for performance. * * @var array */ private $webfont = array(); /** * Checks if the given webfont schema is valid. * * @since 5.9.0 * * @param array $webfont Webfont to validate. * @return bool True when valid. False when invalid. */ public function is_valid_schema( array $webfont ) { $is_valid = ( $this->is_valid_provider( $webfont ) && $this->is_valid_font_family( $webfont ) ); if ( ! $is_valid ) { return false; } if ( 'local' === $webfont['provider'] || array_key_exists( 'src', $webfont ) ) { $is_valid = $this->is_src_valid( $webfont ); } return $is_valid; } /** * Checks if the provider is validate. * * @since 5.9.0 * * @param array $webfont Webfont to validate. * @return bool True if valid. False if invalid. */ private function is_valid_provider( array $webfont ) { // @todo check if provider is registered. if ( empty( $webfont['provider'] ) || ! is_string( $webfont['provider'] ) ) { trigger_error( __( 'Webfont provider must be a non-empty string.' ) ); return false; } return true; } /** * Checks if the font family is validate. * * @since 5.9.0 * * @param array $webfont Webfont to validate. * @return bool True when valid. False when invalid. */ private function is_valid_font_family( array $webfont ) { if ( empty( $webfont['font-family'] ) || ! is_string( $webfont['font-family'] ) ) { trigger_error( __( 'Webfont font family must be a non-empty string.' ) ); return false; } return true; } /** * Checks if the "src" value is valid. * * @since 5.9.0 * * @param array $webfont Webfont to validate. * @return bool True if valid. False if invalid. */ private function is_src_valid( $webfont ) { if ( empty( $webfont['src'] ) || ( ! is_string( $webfont['src'] ) && ! is_array( $webfont['src'] ) ) ) { trigger_error( __( 'Webfont src must be a non-empty string or an array of strings.' ) ); return false; } foreach ( (array) $webfont['src'] as $src ) { if ( ! is_string( $src ) ) { trigger_error( __( 'Each webfont src must be a non-empty string.' ) ); return false; } if ( ! $this->is_src_value_valid( $src ) ) { trigger_error( __( 'Webfont src must be a valid URL or a data URI.' ) ); return false; } } return true; } /** * Checks if the given `src` value is valid. * * @since 5.9.0 * * @param string $src Source to validate. * @return bool True when valid. False when invalid. */ private function is_src_value_valid( $src ) { // Validate data URLs. if ( preg_match( '/^data:.+;base64/', $src ) ) { return true; } // Validate URLs. if ( filter_var( $src, FILTER_VALIDATE_URL ) ) { return true; } // Check if it's a URL starting with "//" (omitted protocol). if ( 0 === strpos( $src, '//' ) ) { return true; } // Check if it's a relative URL. if ( 0 === strpos( $src, 'file:./' ) ) { return true; } return false; } /** * Sets valid properties. * * @since 5.9.0 * * @param array $webfont Webfont definition. * @return array Updated webfont. */ public function set_valid_properties( array $webfont ) { $this->webfont = array_merge( $this->basic_schema, $webfont ); $this->set_valid_font_face_property(); $this->set_valid_font_style(); $this->set_valid_font_weight(); $this->set_valid_font_display(); $webfont = $this->webfont; $this->webfont = array(); // Reset property. return $webfont; } /** * Checks if the CSS property is valid for @font-face. * * @since 5.9.0 */ private function set_valid_font_face_property() { foreach ( array_keys( $this->webfont ) as $property ) { /* * Skip valid configuration parameters (these are configuring the webfont * but are not @font-face properties. */ if ( 'provider' === $property ) { continue; } if ( ! in_array( $property, $this->font_face_properties, true ) ) { unset( $this->webfont[ $property ] ); } } } /** * Checks if the font style is validate. * * @since 5.9.0 */ private function set_valid_font_style() { // If empty or not a string, trigger an error and then set the default value. if ( empty( $this->webfont['font-style'] ) || ! is_string( $this->webfont['font-style'] ) ) { trigger_error( __( 'Webfont font style must be a non-empty string.' ) ); } elseif ( // Bail out if the font-weight is a valid value. in_array( $this->webfont['font-style'], self::VALID_FONT_STYLE, true ) || preg_match( '/^oblique\s+(\d+)%/', $this->webfont['font-style'] ) ) { return; } $this->webfont['font-style'] = 'normal'; } /** * Sets a default font weight if invalid. * * @since 5.9.0 */ private function set_valid_font_weight() { // If empty or not a string, trigger an error and then set the default value. if ( empty( $this->webfont['font-weight'] ) || ! is_string( $this->webfont['font-weight'] ) ) { trigger_error( __( 'Webfont font weight must be a non-empty string.' ) ); } elseif ( // Bail out if the font-weight is a valid value. // Check if value is a single font-weight, formatted as a number. in_array( $this->webfont['font-weight'], self::VALID_FONT_WEIGHT, true ) || // Check if value is a single font-weight, formatted as a number. preg_match( '/^(\d+)$/', $this->webfont['font-weight'], $matches ) || // Check if value is a range of font-weights, formatted as a number range. preg_match( '/^(\d+)\s+(\d+)$/', $this->webfont['font-weight'], $matches ) ) { return; } // Not valid. Set the default value. $this->webfont['font-weight'] = '400'; } /** * Sets a default font display if invalid. * * @since 5.9.0 */ private function set_valid_font_display() { if ( ! empty( $this->webfont['font-display'] ) && in_array( $this->webfont['font-display'], self::VALID_FONT_DISPLAY, true ) ) { return; } $this->webfont['font-display'] = 'fallback'; } } class Profiler { private $validator; private $total_in_microseconds = 0.0; private $cycles = 0; public function __construct( $validator ) { $this->validator = $validator; } public function register( array $webfont ) { $webfont = $this->convert_to_kabeb_case( $webfont ); $this->cycles++; $start_time = microtime( true ); // Validate schema. if ( ! $this->validator->is_valid_schema( $webfont ) ) { // return ''; // Skip for this test. } $webfont = $this->validator->set_valid_properties( $webfont ); // Do the registration. // Get stats. $end_time = microtime( true ); $this->total_in_microseconds += ( $end_time - $start_time ) * 1000000.0; // store in microseconds. } private function convert_to_kabeb_case( array $webfont ) { $kebab_case = preg_replace( '/(?<!^)[A-Z]/', '-$0', array_keys( $webfont ) ); $kebab_case = array_map( 'strtolower', $kebab_case ); return array_combine( $kebab_case, array_values( $webfont ) ); } public function get_avg_microseconds() { return $this->total_in_microseconds / $this->cycles; } } // Let's Go! $profiler = new Profiler( new WP_Webfonts_Schema_Validator() ); $webfont = array( 'fontFamily' => 'Source Serif Pro', 'fontWeight' => '200 900', 'fontStyle' => 'normal', 'fontStretch' => 'normal', 'src' => 'file:./assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2', 'provider' => 'local', ); /** * Benchmark the average time the Validator takes to validate a single webfont. * The profiler is set to 10,000 cycles to get a fair sampling and distribution. */ $num_time_to_run_validator = 10000; // do work. for ( $i = 1; $i <= $num_time_to_run_validator; $i++ ) { $profiler->register( $webfont ); } printf( "Ran %d in %s microseconds", $num_time_to_run_validator, number_format( $profiler->get_avg_microseconds(), 4 ) );

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.3.60.0100.07817.00
8.3.50.0100.05418.41
8.3.40.0160.04619.39
8.3.30.0030.06818.88
8.3.20.0040.03224.18
8.3.10.0100.05924.66
8.3.00.0060.02826.16
8.2.180.0190.06525.92
8.2.170.0000.06319.20
8.2.160.0030.05822.96
8.2.150.0100.06125.66
8.2.140.0070.02724.66
8.2.130.0130.04626.16
8.2.120.0070.02719.28
8.2.110.0130.04220.78
8.2.100.0070.05120.47
8.1.280.0100.05525.92
8.1.270.0070.02624.66
8.1.260.0130.02326.35
8.1.250.0100.03028.09
8.1.240.0110.04318.77
8.1.230.0070.04522.32
8.0.110.0080.04617.15
7.4.240.0020.05216.87

preferences:
42.23 ms | 401 KiB | 5 Q