patternphpMinor
Alphabetical navigation
Viewed 0 times
alphabeticalnavigationstackoverflow
Problem
This is an alphabetical navigation which shows only the letter that have posts in both that letter and the currently filtered "genero" taxonomy term.
I use multiple taxonomy queries to find "artistas" posts that, for example, are tagged as both "rock" and "funk".
The function works perfectly and outputs exactly what I want it to, but the multiple loops are really lagging the load time and I'm uncertain of how to optimize the function.
```
'.strtoupper($i).'';
return $output;
}
function is_alfa() {
$alfa = filter_input(INPUT_GET, 'alfa', FILTER_SANITIZE_STRING | FILTER_SANITIZE_STRIPPED);
$is_alfa = ( ! $alfa ? is_tax('alfa') : true );
return $is_alfa;
}
function has_artists($i, $genre) {
$has_artists = false;
if(term_exists( $i, 'alfa' )) {
$alfas[] = array(
'taxonomy' => 'alfa',
'terms' => $i,
'field' => 'slug',
);
$genres[] = array(
'taxonomy' => 'genero',
'terms' => $genre,
'field' => 'slug',
'operator' => 'AND',
);
$termquery['post_type'] = 'artistas';
if(empty($genre)) {
$termquery['tax_query'] = $alfas;
} else {
$termquery['tax_query'] = array_merge($genres, $alfas);
$termquery['tax_query']['relation'] = "AND";
}
$has_artists = get_posts($termquery);
}
return $has_artists;
}
function alfa_nav_output($home, $uri, $taxonomyvar) {
foreach(range('a', 'z') as $i) :
$current = ($i == $taxonomyvar) ? "bg1 round-res" : "";
$empty_alfa = empty_alfa($current, $i, $taxonomyvar);
if ( term_exists( $i, 'alfa' ) ){
if( has_artists($i,$genre) && $i != $taxonomyvar ) {
if(empty($genre)) {
$link = $home.'?alfa='.$i.$orden;
} else {
$genrestring = (is_array($genre) ? implode('+',$genre) : $genrestring = $genre );
I use multiple taxonomy queries to find "artistas" posts that, for example, are tagged as both "rock" and "funk".
The function works perfectly and outputs exactly what I want it to, but the multiple loops are really lagging the load time and I'm uncertain of how to optimize the function.
```
'.strtoupper($i).'';
return $output;
}
function is_alfa() {
$alfa = filter_input(INPUT_GET, 'alfa', FILTER_SANITIZE_STRING | FILTER_SANITIZE_STRIPPED);
$is_alfa = ( ! $alfa ? is_tax('alfa') : true );
return $is_alfa;
}
function has_artists($i, $genre) {
$has_artists = false;
if(term_exists( $i, 'alfa' )) {
$alfas[] = array(
'taxonomy' => 'alfa',
'terms' => $i,
'field' => 'slug',
);
$genres[] = array(
'taxonomy' => 'genero',
'terms' => $genre,
'field' => 'slug',
'operator' => 'AND',
);
$termquery['post_type'] = 'artistas';
if(empty($genre)) {
$termquery['tax_query'] = $alfas;
} else {
$termquery['tax_query'] = array_merge($genres, $alfas);
$termquery['tax_query']['relation'] = "AND";
}
$has_artists = get_posts($termquery);
}
return $has_artists;
}
function alfa_nav_output($home, $uri, $taxonomyvar) {
foreach(range('a', 'z') as $i) :
$current = ($i == $taxonomyvar) ? "bg1 round-res" : "";
$empty_alfa = empty_alfa($current, $i, $taxonomyvar);
if ( term_exists( $i, 'alfa' ) ){
if( has_artists($i,$genre) && $i != $taxonomyvar ) {
if(empty($genre)) {
$link = $home.'?alfa='.$i.$orden;
} else {
$genrestring = (is_array($genre) ? implode('+',$genre) : $genrestring = $genre );
Solution
To find bottle necks in your code, take the following code and wrap it around the code you wish to benchmark. Take a look at the documentation for more information.
Now, on to your current code. I can't tell you the parts that are running slow because: One, there is just too much here; And two, there's not enough here. Kind of an Oxymoron, but it makes sense, honest! So, instead I will just look at your code and give feedback. I will limit myself to just looking for redundancies so that it focuses more on your speed issues than anything else.
Now, ignoring what I just said, here's one fix you can do that is more design oriented rather than performance oriented. However it could have the added benefit of increasing your programs performance as well, which is why I mentioning it. The most glaring issue I have with your code is that your functions are HUGE! Functions are, first and foremost, meant to hold repetitive tasks. Secondly they are meant to make your code cleaner. I actually had to return to the top of your code while reading this to ensure that I wasn't looking at procedural code because I had forgotten I was looking at a function and thought that you had put another function in the middle of your code.
Update: Upon further observation, I still found this to be true. Your
So first thing to do, is break your functions up so that they are cleaner. Added benefit will be that it will be easier to debug and read and it will be easier to wrap a function in those
I didn't actually change any of your code here, I only moved a chunk of it to a new function
Here's the first performance issue I have spotted. Change the following:
To this:
If you only want the last bit of a string that you know the starting positon of, you can just use substring. Exploding it into an array just to get the last element probably takes up more resources than are necessary. I'm not 100% sure about this, but it makes sense. Use that
Now, for the second performance issue I spotted. Your entire
```
function has_artists($i, $genre) {
$temp = array(
'taxonomy' => 'alfa',
'terms' => $i,
'field' => 'slug',
);
if( ! empty($genre)) {
$temp['taxonomy'] = 'genero';
$temp['terms'] = $genre;
if(is_array($genre)) { $temp['operator'] = 'AND'; }
$genres[] = $temp;
$termquery['tax_query']['relation'] = "AND";
}
$alfaquery = array();//was not defined and should be
$alfaquery[] = $temp;
$
$start = microtime(true);
//code to benchmark.
$time = microtime(true) - $start;
echo "task took $time seconds";Now, on to your current code. I can't tell you the parts that are running slow because: One, there is just too much here; And two, there's not enough here. Kind of an Oxymoron, but it makes sense, honest! So, instead I will just look at your code and give feedback. I will limit myself to just looking for redundancies so that it focuses more on your speed issues than anything else.
Now, ignoring what I just said, here's one fix you can do that is more design oriented rather than performance oriented. However it could have the added benefit of increasing your programs performance as well, which is why I mentioning it. The most glaring issue I have with your code is that your functions are HUGE! Functions are, first and foremost, meant to hold repetitive tasks. Secondly they are meant to make your code cleaner. I actually had to return to the top of your code while reading this to ensure that I wasn't looking at procedural code because I had forgotten I was looking at a function and thought that you had put another function in the middle of your code.
Update: Upon further observation, I still found this to be true. Your
has_artists() function is in the middle of your bam_artist_alfa() function. Don't do this. Its hard to tell from your code because of how long it is, so I don't know if it was just a typo, or if you legitamately have it this way. This may even be part of your performance problem.So first thing to do, is break your functions up so that they are cleaner. Added benefit will be that it will be easier to debug and read and it will be easier to wrap a function in those
microtime blocks I showed you earlier than those long lines of code you have now. And as I already mentioned, it could have the added benefit of boosting your performance. Here's an example:function bam_artist_alfa() {
$taxonomy = 'alfa';
$uri = my_url();
$home = 'http://buenosairesmusic.com/';
// save the terms that have posts in an array as a transient
$start = microtime(true);
check_taxonomy();//new function
$time = microtime(true) - $start;
echo "It took $time seconds to save the terms";
//plus all other code, I won't copy it all here
}
function check_taxonomy() {//one of those new functions in bam_artist_alfa
if ( false === ( $alphabet = get_transient( 'bam_archive_alphabet' ) ) ) {
// It wasn't there, so regenerate the data and save the transient
$terms = get_terms($taxonomy);
$alphabet = array();
if($terms){
foreach ($terms as $term){
$alphabet[] = $term->slug;
}
}
set_transient( 'bam_archive_alphabet', $alphabet );
}
}
etc...I didn't actually change any of your code here, I only moved a chunk of it to a new function
check_taxonomy(). Break your code up into similar, logical, blocks and this will help your code drastically. Both in readability, and hopefully, performance.Here's the first performance issue I have spotted. Change the following:
$genre = explode('/',$genre);
$genre = end($genre);To this:
$genre = substr($genre, - strrpos($genre, '/'));If you only want the last bit of a string that you know the starting positon of, you can just use substring. Exploding it into an array just to get the last element probably takes up more resources than are necessary. I'm not 100% sure about this, but it makes sense. Use that
microtime function on both methods to determine which is faster for you.Now, for the second performance issue I spotted. Your entire
has_artists() function. I'm having a real problem getting through all these arrays, some of which are identical. If you find yourself reusing information, set it up higher in the code to be reused as the code progresses. Even if it is not used for certain parts, it will not hurt anything to have it declared. I ended up rewritting this entire function. Compare yours to mine. The size difference alone is obvious. There was a lot of redundancy here, and even reduced, it is still rather confusing and could probably be compressed more, but I don't understand it enough to try.```
function has_artists($i, $genre) {
$temp = array(
'taxonomy' => 'alfa',
'terms' => $i,
'field' => 'slug',
);
if( ! empty($genre)) {
$temp['taxonomy'] = 'genero';
$temp['terms'] = $genre;
if(is_array($genre)) { $temp['operator'] = 'AND'; }
$genres[] = $temp;
$termquery['tax_query']['relation'] = "AND";
}
$alfaquery = array();//was not defined and should be
$alfaquery[] = $temp;
$
Code Snippets
$start = microtime(true);
//code to benchmark.
$time = microtime(true) - $start;
echo "task took $time seconds";function bam_artist_alfa() {
$taxonomy = 'alfa';
$uri = my_url();
$home = 'http://buenosairesmusic.com/';
// save the terms that have posts in an array as a transient
$start = microtime(true);
check_taxonomy();//new function
$time = microtime(true) - $start;
echo "It took $time seconds to save the terms";
//plus all other code, I won't copy it all here
}
function check_taxonomy() {//one of those new functions in bam_artist_alfa
if ( false === ( $alphabet = get_transient( 'bam_archive_alphabet' ) ) ) {
// It wasn't there, so regenerate the data and save the transient
$terms = get_terms($taxonomy);
$alphabet = array();
if($terms){
foreach ($terms as $term){
$alphabet[] = $term->slug;
}
}
set_transient( 'bam_archive_alphabet', $alphabet );
}
}
etc...$genre = explode('/',$genre);
$genre = end($genre);$genre = substr($genre, - strrpos($genre, '/'));function has_artists($i, $genre) {
$temp = array(
'taxonomy' => 'alfa',
'terms' => $i,
'field' => 'slug',
);
if( ! empty($genre)) {
$temp['taxonomy'] = 'genero';
$temp['terms'] = $genre;
if(is_array($genre)) { $temp['operator'] = 'AND'; }
$genres[] = $temp;
$termquery['tax_query']['relation'] = "AND";
}
$alfaquery = array();//was not defined and should be
$alfaquery[] = $temp;
$termquery['tax_query'] = array_merge($genres, $alfaquery);
$termquery['post_type'] = 'artistas';
$has_artists = get_posts($termquery);
return $has_artists;
}Context
StackExchange Code Review Q#11182, answer score: 5
Revisions (0)
No revisions yet.