<commit_before>### Performance

Writing performant code is absolutely critical, especially at the enterprise level. There are a number of strategies and best practices we must employ to ensure our code is optimized for high-traffic situations.

#### Efficient Database Queries

When querying the database in WordPress, you should generally use a [```WP_Query```](http://codex.wordpress.org/Class_Reference/WP_Query) object. ```WP_Query``` objects take a number of useful arguments and do things behind-the-scenes that other database access methods such as [```get_posts()```](https://developer.wordpress.org/reference/functions/get_posts/) do not.

Here are a few key points:

* Only run the queries that you need.

A new ```WP_Query``` object runs five queries by default, including calculating pagination and priming the term and meta caches. Each of the following arguments will remove a query:

1. ```'no_found_rows' => true```: useful when pagination is not needed.
2. ```'update_post_meta_cache' => true```: useful when post meta will not be utilized.
3. ```'update_post_term_cache' => true```: useful when taxonomy terms will not be utilized.
4. ```'fields' => 'ids'```: useful when only the post IDs are needed (less typical).

* Do not use ```posts_per_page => -1```.

This is a performance hazard. What if we have 100,000 posts? This could crash the site. If you are writing a widget, for example, and just want to grab all of a custom post type, determine a reasonable upper limit for your situation.

```php
<?php
// Query for 500 posts.
new WP_Query( array(
  'posts_per_page' => 500,
));
?>
```

* Do not use ```$wpdb``` or ```get_posts()``` unless you have good reason.

```get_posts()``` actually calls ```WP_Query```, but calling ```get_posts()``` directly bypasses a number of filters by default. Not sure whether you need these things or not? You probably don't.

* If you don't plan to paginate query results, always pass ```no_found_rows => true``` to ```WP_Query```.

This will tell WordPress not to run ```SQL_CALC_FOUND_ROWS``` on the SQL query drastically speeding up your query. ```SQL_CALC_FOUND_ROWS``` calculates the total number of rows in your query which is required to know the total amount of "pages" for pagination.

```php
<?php
// Skip SQL_CALC_FOUND_ROWS for performance (no pagination).
new WP_Query( array(
  'no_found_rows' => true,
));
?>
```

* A [taxonomy](http://codex.wordpress.org/Taxonomies) is a tool that lets us group or classify posts.

[Post meta](http://codex.wordpress.org/Custom_Fields) lets us store unique information about specific posts. As such the way post meta is stored does not facilitate efficient post lookups. Generally, looking up posts by post meta should be avoided (sometimes it can't). If you have to use one, make sure that it's not the main query and that it's cached.

* Passing ```cache_results => false``` to ```WP_Query``` is usually not a good idea.

If ```cache_results => true``` (which is true by default if you have caching enabled and an object cache setup), ```WP_Query``` will cache the posts found among other things. It makes sense to use ```cache_results => false``` in rare situations (possibly WP-CLI commands).

* Multi-dimensional queries should be avoided.

Examples of multi-dimensional queries include:

  * Querying for posts based on terms across multiple taxonomies
  * Querying multiple post meta keys
  
Each extra dimension of a query joins an extra database table. Instead, query by the minimum number of dimensions possible and use PHP to filter out results you don't need.

Here is an example of a 2-dimensional query:

```php
<?php
// Query for posts with both a particular category and tag.
new WP_Query( array(
  'category_name' => 'cat-slug',
  'tag' => 'tag-slug',
));
?>
```

#### Caching

Caching is simply the act of storing computed data somewhere for later use, and is an incredibly important concept in WordPress. There are different ways to employ caching, and often multiple methods will be used.

##### The "Object Cache"

Object caching is the act of caching data or objects for later use. In the context of WordPress, objects are cached in memory so they can be retrieved quickly.

In WordPress, the object cache functionality provided by [```WP_Object_Cache```](https://developer.wordpress.org/reference/classes/wp_object_cache/), and the [Transient API](https://codex.wordpress.org/Transients_API) are great solutions for improving performance on long-running queries, complex functions, or similar.

On a regular WordPress install, the difference between transients and the object cache is that transients are persistent and would write to the options table, while the object cache only persists for the particular page load.

On environments with a persistent caching mechanism (i.e. [Memcache](http://memcached.org/), [Redis](http://redis.io/), or similar) enabled, the transient functions become wrappers for the normal ```WP_Object_Cache``` functions. The objects are identically stored in the object cache and will be available across page loads.

Note: as the objects are stored in memory, you need to consider that these objects can be cleared at any time and that your code must be constructed in a way that it would not rely on the objects being in place.

This means you always need to ensure you check for the existence of a cached object and be ready to generate it in case it's not available. Here is an example:

```php<commit_msg>Cleanup markdown<commit_after>### Performance

Writing performant code is absolutely critical, especially at the enterprise level. There are a number of strategies and best practices we must employ to ensure our code is optimized for high-traffic situations.

#### Efficient Database Queries

When querying the database in WordPress, you should generally use a [```WP_Query```](http://codex.wordpress.org/Class_Reference/WP_Query) object. ```WP_Query``` objects take a number of useful arguments and do things behind-the-scenes that other database access methods such as [```get_posts()```](https://developer.wordpress.org/reference/functions/get_posts/) do not.

Here are a few key points:

* Only run the queries that you need.

    A new ```WP_Query``` object runs five queries by default, including calculating pagination and priming the term and meta caches. Each of the following arguments will remove a query:

    * ```'no_found_rows' => true```: useful when pagination is not needed.
    * ```'update_post_meta_cache' => true```: useful when post meta will not be utilized.
    * ```'update_post_term_cache' => true```: useful when taxonomy terms will not be utilized.
    * ```'fields' => 'ids'```: useful when only the post IDs are needed (less typical).

* Do not use ```posts_per_page => -1```.

    This is a performance hazard. What if we have 100,000 posts? This could crash the site. If you are writing a widget, for example, and just want to grab all of a custom post type, determine a reasonable upper limit for your situation.

    ```php
    <?php
    // Query for 500 posts.
    new WP_Query( array(
      'posts_per_page' => 500,
    ));
    ?>
    ```

* Do not use ```$wpdb``` or ```get_posts()``` unless you have good reason.

    ```get_posts()``` actually calls ```WP_Query```, but calling ```get_posts()``` directly bypasses a number of filters by default. Not sure whether you need these things or not? You probably don't.

* If you don't plan to paginate query results, always pass ```no_found_rows => true``` to ```WP_Query```.

    This will tell WordPress not to run ```SQL_CALC_FOUND_ROWS``` on the SQL query drastically speeding up your query. ```SQL_CALC_FOUND_ROWS``` calculates the total number of rows in your query which is required to know the total amount of "pages" for pagination.

    ```php
    <?php
    // Skip SQL_CALC_FOUND_ROWS for performance (no pagination).
    new WP_Query( array(
      'no_found_rows' => true,
    ));
    ?>
    ```

* A [taxonomy](http://codex.wordpress.org/Taxonomies) is a tool that lets us group or classify posts.

    [Post meta](http://codex.wordpress.org/Custom_Fields) lets us store unique information about specific posts. As such the way post meta is stored does not facilitate efficient post lookups. Generally, looking up posts by post meta should be avoided (sometimes it can't). If you have to use one, make sure that it's not the main query and that it's cached.

* Passing ```cache_results => false``` to ```WP_Query``` is usually not a good idea.

    If ```cache_results => true``` (which is true by default if you have caching enabled and an object cache setup), ```WP_Query``` will cache the posts found among other things. It makes sense to use ```cache_results => false``` in rare situations (possibly WP-CLI commands).

* Multi-dimensional queries should be avoided.

    Examples of multi-dimensional queries include:

      * Querying for posts based on terms across multiple taxonomies
      * Querying multiple post meta keys

    Each extra dimension of a query joins an extra database table. Instead, query by the minimum number of dimensions possible and use PHP to filter out results you don't need.

    Here is an example of a 2-dimensional query:

    ```php
    <?php
    // Query for posts with both a particular category and tag.
    new WP_Query( array(
      'category_name' => 'cat-slug',
      'tag' => 'tag-slug',
    ));
    ?>
    ```

#### Caching

Caching is simply the act of storing computed data somewhere for later use, and is an incredibly important concept in WordPress. There are different ways to employ caching, and often multiple methods will be used.

##### The "Object Cache"

Object caching is the act of caching data or objects for later use. In the context of WordPress, objects are cached in memory so they can be retrieved quickly.

In WordPress, the object cache functionality provided by [```WP_Object_Cache```](https://developer.wordpress.org/reference/classes/wp_object_cache/), and the [Transient API](https://codex.wordpress.org/Transients_API) are great solutions for improving performance on long-running queries, complex functions, or similar.

On a regular WordPress install, the difference between transients and the object cache is that transients are persistent and would write to the options table, while the object cache only persists for the particular page load.

On environments with a persistent caching mechanism (i.e. [Memcache](http://memcached.org/), [Redis](http://redis.io/), or similar) enabled, the transient functions become wrappers for the normal ```WP_Object_Cache``` functions. The objects are identically stored in the object cache and will be available across page loads.

Note: as the objects are stored in memory, you need to consider that these objects can be cleared at any time and that your code must be constructed in a way that it would not rely on the objects being in place.

This means you always need to ensure you check for the existence of a cached object and be ready to generate it in case it's not available. Here is an example:

```php
{'fraction_non_alphanumeric': 0.09011444534558889, 'fraction_numerical': 0.0028836622510588447, 'mean_word_length': 4.351012536162006, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 35, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5076899', 'n_tokens_mistral': 2971, 'n_tokens_neox': 2835, 'n_words': 1520}