• Resolved simonebiffi

    (@simonebiffi)


    Hi there, I was wondering if someone knows how I can optimize, and hopefully dramatically shrink the function below.

    It is used within the function.php of a custom template and it’s used to retrieved custom designs for each of the individual sections of the blog/site. The problem is that it’s immensely long and it seems to cause some little CPU overload on the server.

    Anybody would know how to optimize it? Thanks in advance!

    /********************************************************************
    loading a custom single post template
    ********************************************************************/
    function get_custom_post() {
    
    	global $post, $chic;
    	$get_post_cat = wp_get_post_categories($post->ID);
    	foreach($get_post_cat as $catid ) {
    	$cat = get_category($catid);
    	$the_cat = get_cat_name($cat->cat_ID);
    	}
    
    	// videos
    	$video_sustainability = get_cat_name($chic['video_sustainability_id']);
    	$video_art_and_design = get_cat_name($chic['video_art_design_id']);
    	$video_conscious_living = get_cat_name($chic['video_conscious_living_id']);
    	$video_wellbeing = get_cat_name($chic['video_wellbeing_id']);
    	// Wellbeing
    	$in_the_balance = get_cat_name($chic['in_the_balance_id']);
    	$intimacy = get_cat_name($chic['intimacy_id']);
    	$social_trends = get_cat_name($chic['social_trends_id']);
    	$sustainable_life = get_cat_name($chic['sustainable_life_id']);
    	$wellness_notes = get_cat_name($chic['wellness_notes_id']);
    	// Travel
    	$dream_destinations = get_cat_name($chic['dream_destinations_id']);
    	$globe_trotter = get_cat_name($chic['globe_trotter_id']);
    	$haute_hotels = get_cat_name($chic['haute_hotels_id']);
    	$spas = get_cat_name($chic['spas_id']);
    	$wanderlust = get_cat_name($chic['wanderlust_id']);
    	// Culture
    	$art_and_design = get_cat_name($chic['art_and_design_id']);
    	$books = get_cat_name($chic['books_id']);
    	$cuisine = get_cat_name($chic['cuisine_id']);
    	$on_the_agenda = get_cat_name($chic['on_the_agenda_id']);
    	$photography = get_cat_name($chic['photography_id']);
    	$lifestyle_notes = get_cat_name($chic['lifestyle_notes_id']);
    	// Fashion
    	$style_mantra = get_cat_name($chic['style_mantra_id']);
    	$style_notes = get_cat_name($chic['style_notes_id']);
    	$street_style = get_cat_name($chic['street_style_id']);
    	$trendwatch = get_cat_name($chic['trendwatch_id']);
    	$stylist_on_demand = get_cat_name($chic['stylist_on_demand_id']);
    	$wish_list = get_cat_name($chic['wish_list_id']);
    	// Beauty
    	$must_have_products = get_cat_name($chic['must_have_products_id']);
    	$beauty_trends = get_cat_name($chic['beauty_trends_id']);
    	$dream_destinations = get_cat_name($chic['dream_destinations_id']);
    	$scentsual = get_cat_name($chic['scentsual_id']);
    	$top_tips = get_cat_name($chic['top_tips_id']);
    	$beaute_notes = get_cat_name($chic['beaute_notes_id']);
    	// Celebs
    	$interviews = get_cat_name($chic['interviews_id']);
    	$chicest_celebs = get_cat_name($chic['chicest_celebs_id']);
    	$get_the_look = get_cat_name($chic['get_the_look_id']);
    	$the_good_celebritan = get_cat_name($chic['the_good_celebritan_id']);
    	$the_red_carpet = get_cat_name($chic['the_red_carpet_id']);
    	$celebrity_notes = get_cat_name($chic['celebrity_notes_id']);
    	// Magazine
    	$back_issues = get_cat_name($chic['back_issues_id']);
    	$current_issue = get_cat_name($chic['current_issue_id']);
    	// Competitions
    	$current_competitions = get_cat_name($chic['current_competitions_id']);
    	$past_competitions = get_cat_name($chic['past_competitions_id']);
    
    	// re-set variable for-each
    	// Videos
    	$article_video_sustainability = '/^'. $video_sustainability .'/';
    	$article_video_art_and_design = '/^'. $video_art_and_design .'/';
    	$article_conscious_living = '/^'. $video_conscious_living .'/';
    	$article_video_wellbeing = '/^'. $video_wellbeing .'/';
    	// Wellbeing
    	$article_in_the_balance = '/^'. $in_the_balance .'/';
    	$article_intimacy = '/^'. $intimacy .'/';
    	$article_social_trends = '/^'. $social_trends .'/';
    	$article_sustainable_life = '/^'. $sustainable_life .'/';
    	$article_wellness_notes = '/^'. $wellness_notes .'/';
    	// Travel
    	$gallery_dream_destinations = '/^'. $dream_destinations .'/';
    	$blog_globe_trotter = '/^'. $globe_trotter .'/';
    	$gallery_haute_hotels = '/^'. $haute_hotels .'/';
    	$gallery_spas = '/^'. $spas .'/';
    	$article_wanderlust = '/^'. $wanderlust .'/';
    	// Culture
    	$gallery_art_and_design = '/^'. $art_and_design .'/';
    	$article_books = '/^'. $books .'/';
    	$article_cuisine = '/^'. $cuisine .'/';
    	$article_on_the_agenda = '/^'. $on_the_agenda .'/';
    	$gallery_photography = '/^'. $photography .'/';
    	$article_lifestyle_notes = '/^'. $lifestyle_notes .'/';
    	// Fashion
    	$gallery_style_mantra = '/^'. $style_mantra .'/';
    	$article_style_notes = '/^'. $style_notes .'/';
    	$blog_street_style = '/^'. $street_style .'/';
    	$gallery_trendwatch = '/^'. $trendwatch .'/';
    	$gallery_stylist_on_demand = '/^'. $stylist_on_demand .'/';
    	$gallery_wish_list = '/^'. $wish_list .'/';
    	// Beauty
    	$gallery_must_have_products = '/^'. $must_have_products .'/';
    	$gallery_beauty_trends = '/^'. $beauty_trends .'/';
    	$gallery_scentsual = '/^'. $scentsual .'/';
    	$gallery_top_tips = '/^'. $top_tips .'/';
    	$article_beaute_notes = '/^'. $beaute_notes .'/';
    	// Celebs
    	$article_interviews = '/^'. $interviews .'/';
    	$gallery_chicest_celebs = '/^'. $chicest_celebs .'/';
    	$gallery_get_the_look = '/^'. $get_the_look .'/';
    	$article_the_good_celebritan = '/^'. $the_good_celebritan .'/';
    	$gallery_the_red_carpet = '/^'. $the_red_carpet .'/';
    	$article_celebrity_notes = '/^'. $celebrity_notes .'/';
    	// Magazine
    	$article_back_issues = '/^'. $back_issues .'/';
    	$article_current_issue = '/^'. $current_issue .'/';
    	// Competitions
    	$article_current_competitions = '/^'. $current_competitions .'/';
    	$article_past_competitions = '/^'. $past_competitions .'/';
    
    	// IF condition Videos
    	if (preg_match($article_video_sustainability, $the_cat)) {
    		include TEMPLATEPATH. '/article_video_sustainability.php';
    	} elseif (preg_match($article_video_art_and_design, $the_cat)) {
    		include TEMPLATEPATH. '/article_video_art_design.php';
    	} elseif (preg_match($article_conscious_living, $the_cat)) {
    		include TEMPLATEPATH. '/article_video_conscious_living.php';
    	} elseif (preg_match($article_video_wellbeing, $the_cat)) {
    		include TEMPLATEPATH. '/article_video_wellbeing.php';
    	} 
    
    	// Wellbeing
    	elseif (preg_match($article_in_the_balance, $the_cat)) {
    		include TEMPLATEPATH. '/article_in_the_balance.php';
    	} elseif (preg_match($article_intimacy, $the_cat)) {
    		include TEMPLATEPATH. '/article_intimacy.php';
    	} elseif (preg_match($article_social_trends, $the_cat)) {
    		include TEMPLATEPATH. '/article_social_trends.php';
    	} elseif (preg_match($article_sustainable_life, $the_cat)) {
    		include TEMPLATEPATH. '/article_sustainable_life.php';
    	} elseif (preg_match($article_wellness_notes, $the_cat)) {
    	    include TEMPLATEPATH. '/article_wellness_notes.php';
    	} 
    
    	// Travel
    	elseif (preg_match($gallery_dream_destinations, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_dream_destinations.php';
    	} elseif (preg_match($blog_globe_trotter, $the_cat)) {
    		include TEMPLATEPATH. '/blog_globe_trotter.php';
    	} elseif (preg_match($gallery_haute_hotels, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_haute_hotels.php';
    	} elseif (preg_match($gallery_spas, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_spas.php';
    	} elseif (preg_match($article_wanderlust, $the_cat)) {
    	    include TEMPLATEPATH. '/article_wanderlust.php';
    	} 
    
    	// Culture
    	elseif (preg_match($gallery_art_and_design, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_art_and_design.php';
    	} elseif (preg_match($article_books, $the_cat)) {
    		include TEMPLATEPATH. '/article_books.php';
    	} elseif (preg_match($article_cuisine, $the_cat)) {
    		include TEMPLATEPATH. '/article_cuisine.php';
    	} elseif (preg_match($article_on_the_agenda, $the_cat)) {
    		include TEMPLATEPATH. '/article_on_the_agenda.php';
    	} elseif (preg_match($gallery_photography, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_photography.php';
    	} elseif (preg_match($article_lifestyle_notes, $the_cat)) {
    	    include TEMPLATEPATH. '/article_lifestyle_notes.php';
    	} 
    
    	// Fashion
    	elseif (preg_match($gallery_style_mantra, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_style_mantra.php';
    	} elseif (preg_match($article_style_notes, $the_cat)) {
    		include TEMPLATEPATH. '/article_style_notes.php';
    	} elseif (preg_match($blog_street_style, $the_cat)) {
    		include TEMPLATEPATH. '/blog_street_style.php';
    	} elseif (preg_match($gallery_trendwatch, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_trendwatch.php';
    	} elseif (preg_match($gallery_stylist_on_demand, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_stylist_on_demand.php';
    	} elseif (preg_match($gallery_wish_list, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_wish_list.php';
    	} 
    
    	// Beauty
    	elseif (preg_match($gallery_must_have_products, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_must_have_products.php';
    	} elseif (preg_match($gallery_beauty_trends, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_beauty_trends.php';
    	} elseif (preg_match($gallery_scentsual, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_scentsual.php';
    	} elseif (preg_match($gallery_top_tips, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_top_tips.php';
    	} elseif (preg_match($article_beaute_notes, $the_cat)) {
    	    include TEMPLATEPATH. '/article_beaute_notes.php';
    	} 
    
    	// Celebs
    	elseif (preg_match($article_interviews, $the_cat)) {
    		include TEMPLATEPATH. '/article_interviews.php';
    	} elseif (preg_match($gallery_chicest_celebs, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_chichest_celebs.php';
    	} elseif (preg_match($gallery_get_the_look, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_get_the_look.php';
    	} elseif (preg_match($article_the_good_celebritan, $the_cat)) {
    		include TEMPLATEPATH. '/article_the_good_celebritan.php';
    	} elseif (preg_match($gallery_the_red_carpet, $the_cat)) {
    		include TEMPLATEPATH. '/gallery_the_red_carpet.php';
    	} elseif (preg_match($article_celebrity_notes, $the_cat)) {
    	    include TEMPLATEPATH. '/article_celebrity_notes.php';
    	} 
    
    	// Magazine
    	elseif (preg_match($article_back_issues, $the_cat)) {
    		include TEMPLATEPATH. '/article_magazine.php';
    	} elseif (preg_match($article_current_issue, $the_cat)) {
    		include TEMPLATEPATH. '/article_magazine.php';
    	}
    
    	// Competitions
    	elseif (preg_match($article_current_competitions, $the_cat)) {
    		include TEMPLATEPATH. '/article_competitions.php';
    	} elseif (preg_match($article_past_competitions, $the_cat)) {
    		include TEMPLATEPATH. '/article_competitions.php';
    	} 
    
    	// Conclude
    	else {
    		include TEMPLATEPATH. '/article_general.php';
    	}
    
    }
Viewing 15 replies - 1 through 15 (of 20 total)
  • Good grief! Is it absolutely essential to have so many completely independant templates? Why not use the body_class() with the category name & the post name added as a classes. Then style using CSS?

    Thread Starter simonebiffi

    (@simonebiffi)

    Hi Esmi,

    Thanks a mille for the prompt reply. Unfortunately it is essential to maintain full and differentiated control for each individual category and post.

    As you may see here: http://www.chictoday.com, the entire website runs on a WordPress CMS and each individual channels homepages, categories and especially the individual posts have different layout design also due to advertising and content individuality. And as you can see there are quite a few.

    Do you truly think I could achieve the same using body_class()? If so, I think I’d have to reprogram the entire site, that’s my fear. That’s why I was in the meantime looking for a possible ‘shrinking’ optimized solution of the code above.

    I think you can cut out a lot of database calls by changing this:

    // videos
    	$video_sustainability = get_cat_name($chic['video_sustainability_id']);
    	$video_art_and_design = get_cat_name($chic['video_art_design_id']);

    to this:

    $all_cats = get_categories();
       foreach ($all_cats as $one_cat) {
          $cat_by_id[$one_cat->term_id] = $one_cat;
       }
       // videos
       $video_sustainability = $cat_by_id[$chic['video_sustainability_id']]->name;
       $video_art_and_design = $cat_by_id[$chic['video_art_design_id']]->name;

    Also, preg_match is relatively expensive, so if you can get rid of it, it will save cpu. If you are using it just to make sure the whole string matches, you can use the ‘===’ operator like this;

    // IF condition Videos
       if ($video_sustainability === $the_cat) {
          include TEMPLATEPATH. '/article_video_sustainability.php';
    Thread Starter simonebiffi

    (@simonebiffi)

    WOW, that really shrank the entire function dramatically, and it is working perfectly. Now I will need to wait to check the new CPU report from the server to see if I can notice substantial improvement.

    Thanks a mille, vtxyzzy!!! Much appreciated!

    Glad it seems to work.

    One other thing I thought of, but it is not as clean as the ones above, and may not be possible. If you create a .php file for each category, named the same as the category, then you won’t need any of the code above. Just include TEMPLATEPATH . $the_cat;.

    If your CPU report is good, please use the dropdown at top right to mark this topic ‘Resolved’.

    Thread Starter simonebiffi

    (@simonebiffi)

    Just received the CPU report and unfortunately it doesn’t seems to get any better. At this point I might even begin thinking that it could be a RSS related issue?

    The report shows that all major hits fall on the direct categories permalink, e.g.:
    www.domain.com/category/namecategory1/
    www.domain.com/category/namecategory2/
    , rather than direct request to files.

    What frustrates me is that now I literally eliminated all plug-ins (it only uses Disqus Comments and Page-Number), and this problem manifested immediately after the upgrade to WP 2.9.1

    I would suspect something in the individual included files. Pick the top two and see if you can make them more efficient.

    Thread Starter simonebiffi

    (@simonebiffi)

    Is it perhaps possible that the array generated by this script at each visit (request), after the 2.9.1 upgrade, forces the server to write for each individual ‘check-if’ option of the categories enlisted? Is it perhaps that the script needs now to be altered with new WP tags?

    global $post, $chic;
    $get_post_cat = wp_get_post_categories($post->ID);
    foreach($get_post_cat as $catid ) {
    $cat = get_category($catid);
    $the_cat = get_cat_name($cat->cat_ID);
    }

    In few words, what I notice from the CPU report is that all categories receive the same amount of hits/requests, as if an automated refreshed action would call them all at once at each single time an individual category is requested.

    Besides, before 2.9.1 it never happened that categories’ permalinks requests would write/overload the server at all. I thought it could be any new updated plugin, but now that I removed them all I am left to think that it must be due to the function above? Did you eventually hear of any other similar situation so far? This really is frustrating.

    The preg_match will be costing you the most, unless it’s specifically required you should look at alternative methods..

    strpos might be suited..

    Also bear in mind, bits like this..

    foreach($get_post_cat as $catid ) {
    $cat = get_category($catid);
    $the_cat = get_cat_name($cat->cat_ID);
    }

    ..i believe in calling “get_category” or “get_cat_name”, you’ll be doing a single query for each of those, that’s possibly alot of queries when you’re running through a loop.. WordPress functions are usually for convenience, performance secondary …

    I find the term functions faster myself, get_term, get_terms, get_terms_by … etc.. when getting category data…

    Thread Starter simonebiffi

    (@simonebiffi)

    Thanks for the tips, t31os_, much appreciated.

    In fact my fear is that the overload might be caused by the use of “get_category” or “get_cat_name” in the very first parsing of the function.

    The variations suggested by vtxyzzy to streamline the entire function work perfectly and slim down the entire block of code dramatically; unfortuntely I would not have a clue as per how to optimize the loop above to prevent it to query each of the categories enlisted.

    I tried to search and implement the “get_terms” this way, but it doesn’t work. Unfortunately I’m quite dense at these things πŸ™‚

    $get_post_cat = get_terms(category, $post->ID);
    foreach($get_post_cat as $catid ) {
    $cat = get_terms(category, $catid);
    $the_cat = get_terms(category, $cat->cat_ID);
    }
    
    $all_cats = get_categories();
    foreach ($all_cats as $one_cat) {
    $cat_by_id[$one_cat->term_id] = $one_cat;
    }

    Any idea as per how this could be optimzed? Thanks a mille in advance.

    Dump the data when testing (print_r, var_dump), if you know PHP enough to write it, then it’s just a case of sitting down for an hour or two and running simulations with varying pieces of code..

    As much as i love to help, i’m only really prepared to offer suggestions.

    My advice is to try and get as much data as you can in as few queries as you can… and try to avoid (where possible), the get_xxx calls inside loops … because as i said before, that’s generally a single query for “each” of them..
    If it means you have to do one complex query at the start of your script, then do it, it’ll work out faster then doing several simple ones..
    If it means writing your own query, instead of using the get_xxx functions, then do it…

    What’s the total queries on the page, as is?

    The call to wp_get_post_categories below should only retrieve the categories for the current post. So, unless each post has a large number of categories, this code should not be expensive.

    global $post, $chic;
    $get_post_cat = wp_get_post_categories($post->ID);
    foreach($get_post_cat as $catid ) {
    $cat = get_category($catid);
    $the_cat = get_cat_name($cat->cat_ID);
    }

    Also, what about the code that sets up the $chic array. I’ll bet that is making a lot of database calls for the categories, probably at least one call for each category. If you create a unique .php file for each category, you might eliminate this as well.

    Thread Starter simonebiffi

    (@simonebiffi)

    Oh mamma mia, that’s unfortuntely asking a bit too much of myself, LOL.

    I’ve designed and put togheter the entire site by snapping code here and there and knowing some very basics of PHP to ‘survive’, but for as much as I’d love to learn all this very much into depth, I need to realize that am not truly a techy dude πŸ™‚

    Queries vary based on which page is loaded; the infamous function above is actually loaded each single time there is a page/visit request since it’s embedded in functions.php, that’s why the overload, regardless of the area of the website you are in, either landing from referral or inner navigation, the function will always run at request. That’s why am struggling to find a way to bypass the entire get_categories array.

    Unfortunately I am running a quite complex website, but if it wasn’t for this very sudden obstacle, I’d say that WordPress really does its work finely. Any help will be TREMENDOUSLY appreciated πŸ™‚

    Thread Starter simonebiffi

    (@simonebiffi)

    Thank for the hints, vtxyzzy.

    Each individual post is always categorized under one sole category, never to two or more.

    The ‘global $chic;’ variable is set within an external ‘config.inc’ file that in fact sets individual categories as follows:

    $chic['wellbeing_id'] = 584;
    $chic['in_the_balance_id'] = 9195;
    $chic['intimacy_id'] = 9197;
    ...etc.

    This in fact means that the variable requires every time to reload the categories values from the outside and hence forces to query each one of them every time.

    Altough at the very beginning of functions.php it seems that the variable is loaded only once and not repeatedly:

    include_once TEMPLATEPATH. '/config.inc.php';
    $_SESSION['style'] = $chic['style'];

    Do you think I should simply fuse together the two files into the single functions.php?

    Well, the $chic array is hard-coded, so no database activity there. I don’t see any advantage in merging it with functions.php.

    As I said before, the code below is almost certainly NOT the cause of the problem since each post is in only one category. The loop in fact will only be run once per post.

    global $post, $chic;
    $get_post_cat = wp_get_post_categories($post->ID);
    foreach($get_post_cat as $catid ) {
    $cat = get_category($catid);
    $the_cat = get_cat_name($cat->cat_ID);
    }

    I am leaning toward thinking the cause is in the many template files. You should examine them to be sure they do not contain loops that cause database queries inside the loop. Can you post one of the files in wordpress.pastebin.ca and give us the link to it?

    As a last point, I do think you over estimate the difficulty in creating a unique .php file for each category. You already are getting the cat_ID in the first loop. So, instead of all the if === tests, if you save it in a variable called $catID, like this:

    $get_post_cat = wp_get_post_categories($post->ID);
    foreach($get_post_cat as $catid ) {
       $catID = get_category($catid);
    }

    you could use just a single

    include TEMPLATEPATH . "cattemplate-$catID.php";

    Now, using your ‘in_the_balance_id’ = 9195 for example, you would create a file called cattemplate-9195.php. It would contain this:

    <?php include TEMPLATEPATH. '/article_in_the_balance.php'; ?>

    And that’s it.

Viewing 15 replies - 1 through 15 (of 20 total)
  • The topic ‘How to optimize this function’ is closed to new replies.