Elliott C. Back: In Aere Aedificare

Office 12: The New UI

Posted in Microsoft, Graphics, Web 2.0, Interface, UI by Elliott Back on July 27th, 2006.

There’s a lot to be said about Microsoft’s Office 12 / 2007 Beta 2 product, but this post will only focus on the graphical interface elements that have changed or been improved from its predecessors. Office 2007 is rich in tools like the new menu-bars, smooth zooming and scrolling, word counts and improved statistics in the tray, a totally new blue theme, a new loading screen and more.

When you first start Office 12 Beta, you get a cool loading screen:
office-12-loading-screen.jpg

The first thing you’ll want to do is open a document. However, the new menu system puts the File menu on a strange windows shaped button:

office-12-file-menu.jpg

The recent documents space is much larger and easy to navigate, and allows you to pin oft-used documents in place for future reference. The “Options” and “Exit” options are also on this massive, and poorly designed menu. You’ll notice it tried to bring a task oriented approach to managing the document with the “Finish,” “Share,” and “Print” commands, but leaves “New,” “Open,” “Upgrade,” and “Save” to languish by themselves instead of under a common “Create” task.

Office Supplies - Office Products - Office Supply - Discount - Wholesale - Cheap Your single source for Office Supplies, Desks, Office Chairs, Office Furniture, Equipment, Cleaning Supplies, Janitorial Supplies at wholesale discoun

Optimizing Wordpress Performance & Speed

Posted in Blogging, Code, Performance, Wordpress by Elliott Back on July 27th, 2006.

We start with a fresh copy of Wordpress 2.03, fresh from the Wordpress download center. Our goal is to figure out what parts are slow and can be improved. We’re not interested in sacrificing features or existing code for speed, like Lightpress has done. Rather, we’d like to identify the worst performers and improve them, if possible, in the default install.

Our microscope will be XDebug, a PHP performance tool that we’ve installed as a zend extension on our server. It’s a C module that keeps track of the time spent running PHP code, so we can grab and analyse its output to determine what Wordpress is doing under the hood.

Our data set will be all the posts, comments, and pages from this blog. Currently, that is 1405 posts with 6977 comments and 4 pages. This should provide ample material for testing. The database will be optimized after importing.

Initial profiling

Loading the main Wordpress page produces the following traces:

wordpress-trace-01.jpg

10,000 calls to preg_replace, 6,410 to str_replace, and 2,465 to strstr.

wordpress-trace-02.jpg

wptexturize is the heaviest function at 24.4% of its own code, 5.5% on mysql, and 4.5% on apply_filters. Template loading, and php compilation (require_once) are together 30-40% of the loading, as well.

First optimizations

The first thing I notice is that index.php sets a config variable and just includes another file. Why not just move that define() into wp-blog-header.php? It’ll save a function call, and not a lot of time, but it’s cleaner. Also, the ABSPATH define should be done before any other files are included, and thus copied from wp-config.php to index.php to save a few more function calls. There’s a line that sets the timer with an extra assignment statement.

Nitpicking’s not going to get me anywhere. Let’s take a look at wptexturize. We note that we can replace some preg_replace calls with str_replace, because only static strings are replaced, so we add the [’\’s’,'’s’] to the cockneyreplace array hack. We apply this process to all static strings. We can also convert the strings from slower dynamic double quotes to faster static single quotes, and put the dynamic section into another array, like the static section.

These simple operations reduce the time spent inside wptexturize from 24% to 16%, and the time from 600ms to 200ms. We’ve also reduced the number of preg_replace calls dramatically, from 10,439 to 3,289 and total time from 74ms to 36ms. We’ve gone from 54ms of 6,410 str_replace calls to 29ms of 1,405 calls. Why is this? By calling each function only once we save a lot of extra PHP operations and just hand off a bunch of data to fast, underlying C functions. Interestingly, using array_walk/array_map is not faster than a plain loop.

Here’s the new wptexturize function:


<?php

function wptexturize($text) {
    
$next = true;
    
$output = ‘’;
    
$curl = ‘’;
    
$textarr = preg_split(‘/(<.*>)/Us’, $text, -1, PREG_SPLIT_DELIM_CAPTURE);
    
$stop = count($textarr);
    
    for(
$i = 0; $i < $stop; $i++){
        
$curl = $textarr[$i];
        
      if (isset(
$curl{0}) && ‘<’ != $curl{0} && $next) { // If it’s not a tag
          // static strings
          
$static_characters = array(‘&#8212;’, ‘ &#8212; ‘, ‘&#8211;’, ‘xn--’, ‘&#8230;’, ‘&#8220;’, ‘\’tain\’t’, ‘\’twere’, ‘\’twas’, ‘\’tis’, ‘\’twill’, ‘\’til’, ‘\’bout’, ‘\’nuff’, ‘\’round’, ‘\’cause’, ‘\’s’, ‘\’\'’, ‘ ™’);
          
$static_replacements = array(‘—’, ‘ — ‘, ‘–’, ‘xn&#8211;’, ‘…’, ‘“’, ‘&#8217;tain&#8217;t’, ‘&#8217;twere’, ‘&#8217;twas’, ‘&#8217;tis’, ‘&#8217;twill’, ‘&#8217;til’, ‘&#8217;bout’, ‘&#8217;nuff’, ‘&#8217;round’, ‘&#8217;cause’, ‘&#8217;s’, ‘&#8221;’, ‘ &#8482;’);
          
$curl = str_replace($static_characters, $static_replacements, $curl);
  
          
// regular expressions
          
$dynamic_characters = array(‘/\’(\d\d(?:&#8217;|\’)?s)/’, ‘/(\s|\A|”)\’/’, ‘/(\d+)”/’, ‘/(\d+)\’/’, ‘/(\S)\’([^\’\s])/’, ‘/(\s|\A)”(?!\s)/’, ‘/”(\s|\S|\Z)/’, ‘/\’([\s.]|\Z)/’, ‘/(\d+)x(\d+)/’);
          
$dynamic_replacements = array(‘&#8217;$1′,‘$1&#8216;’, ‘$1&#8243;’, ‘$1&#8242;’, ‘$1&#8217;$2′, ‘$1&#8220;$2′, ‘&#8221;$1′, ‘&#8217;$1′, ‘$1&#215;$2′);    
          
$curl = preg_replace($dynamic_characters, $dynamic_replacements, $curl);
      } elseif (
strstr($curl, ‘<code’) || strstr($curl, ‘<pre’) || strstr($curl, ‘<kbd’ || strstr($curl, ‘<style’) || strstr($curl, ‘<script’))) {
          
// strstr is fast
          
$next = false;
      } else {
          
$next = true;
      }
          
      
$curl = preg_replace(‘/&([^#])(?![a-zA-Z1-4]{1,8};)/’, ‘&#038;$1′, $curl);
      
$output .= $curl;
    }
    
    return
$output;
}

Update: As of change #4511 in 11/21/06 Ryan Boren merged this into Wordpress core code. So you now have it!

What’s next

A new look at the numbers shows the next biggest culprit is apply_filters. Even on a default installation, it’s slow, taking 106ms of its own time, and 438ms total. Unfortunately, there doesn’t look to be an easy way to optimize it. Other slow spots, like get_settings and list_cats are likewise difficult to immediately improve. An easy way to increase performance would be to rewrite the plugins architecture and improve the filters mechanism, but that would mean an API change.

Some good news

It’s not all bad though; here’s how the change to wp-texturize performs, tested on PHP 5 windows on a 1.8 GHz machine, with 10 large entries on the homepage:

ab -n 100 -c 1 http://localhost/test/
Document Length: 190017 bytes
Requests per second: 0.78 [#/sec] (mean)
Time per request: 1278.438 [ms] (mean)

Now, here’s the default install of Wordpress 2.0.3:

ab -n 100 -c 1 http://localhost/test/
Document Length: 189786 bytes
Requests per second: 0.77 [#/sec] (mean)
Time per request: 1297.344 [ms] (mean)

Conclusion

While the new wptexturize function performs well on a server with an opcode cache, the performance increase is lost among other considerations on an “out of the box” configuration. Also, a quick glance at the Wordpress core code shows no easy patches to increase performance by large orders, just design ideas that could be gradually improved over time.

My Friend’s Stock Blog

Posted in Links by Elliott Back on July 26th, 2006.

My friend has a stock blog for the trades and market information she considers. Brand new, but potentially interesting down the road!

Lightning & Thunderstorm Video

Posted in Science, Qualitative, Video, YouTube by Elliott Back on July 25th, 2006.

There was some decent looking lightning in a storm we had here in Phoenix a few days ago, so I made a little video clip of it:

Thunderstorm in Phoenix -

The Best of Craiglist Postings

Posted in Memes, Humour, Web 2.0 by Elliott Back on July 25th, 2006.

Did you know that Craiglist postings can be voted “best of” by the system’s users? The Best of Craiglist is the perfect place to go to find hilarious classified ad rants. As a word of warning, the subject matter is often sexual or adult. Still, there’s plenty a work safe gem to be found:

craiglist-best-of.jpg

For example, there’s a desperate hedge fund manager with actual barrels of crude oil in his apartment to get rid of:

Date: 2004-12-02, 8:20AM EST

Sexy UES hedge fund manager willing to s*ck/f*ck his way out of a crude long position. they told me “it would go up forever”. in any event i have barrels of crude warehousd in my apt. willing to trade s**ual favors for 54.95 a barrel … inquire within this is in or around NYC

Then there’s the naive family guy who wants to give away the doubles he accidentally ordered of family photos:

Date: 2004-06-14, 11:37PM EDT

Hi. I just accidently got doubles for my 35MM color prints which I shot with my Kodak digital camera. I don’t want the doubles so I figured someone on here would want them. They’re no nudes or anything like that. Just pics of me with friends and family, then a few pics of my cats. If you want them email me your home address and i’ll send them off to you. this is in or around bronx

Then there’s the old iPod for a fake girlfriend scheme:

Date: 2004-03-14, 12:50AM EST

Hi, I’m having my parents come visit me sometime in the next two weeks and have lied and told them I am dating someone I am in love with. You will only have to come to one dinner. In exchange for this I will buy you an IPOD - yes new - we walk into the store together and buy a new IPOD. Let me know if this interests you, and if you want to be in a loving relationship with all the benefits it brings ;-) I want to pretend we are totally in love. I am 24, swm, a grad student, italian-american, (not a guido), athletic build. Send pics and i will send you mine, note I check email basically every 3 hours. You should be in your 20’s and athletic (great butt and legs are my main interest when I say athletic).

Hilarious. If you’re an avid gamer, you might find this funny:

Level 72 Paladin Seeking 42+ Rogue, Druid, and Sorceress - m4ww
Date: 2006-06-20, 4:36AM PDT

I am seeking a level 42 or above rogue, druid, and sorceress to help me assault the fortress of Mordria, and for hot kinky s3x. I am the sole holder of the Axe of Fragyholt and am a level 72 Paladin equipped with Def+ 52 plate mail […]

Finally, the winner of the bad title award:

TRADE: My Coke for Your Pot
Date: 2006-05-16, 6:56AM EDT

I have a 12-Can “Fridge Pack” of Coca Cola Zero. What I need is a heavy duty aluminum or non-stick cooking pot suitable for everything from making spaghetti to steaming clams. Will consider other offers!

With enough browsing you’ll find some real gems.

« Previous PageNext Page »