6 August, 2008 | Written by Vincent Tan Leave a Comment

Simple excerpts in WordPress

I have finally decided to plunge into some PHP code in my WordPress template. The reason? My home page is a little long. So are my archive and category pages. I write moderately lengthy posts, so even with 5 posts per page, you might have to scroll a bit.

First, I want to say that I have never learnt PHP. I’m also unfamiliar with the innards of WordPress. But I’m a programmer. The code doesn’t look too hard… so I’m still capable of making small changes.

I’ve heard about the use of excerpts, and because I’m too lazy to set them up properly with the more tag, I’m doing it the simple way. This is the code I used:

<?php if(is_category() || is_archive() || ($postcounter!=1 && !is_single() && !is_page())) {
	the_excerpt();
} else {
	the_content(__('Read more &raquo;'));
} ?>

The the_excerpt() function is used to automatically generate an excerpt. It’s automatic, that’s why it’s simple. Otherwise, I’d have to set up more tags. Under the WordPress panel for that particular post, you can also add in specific text you want to use as an excerpt. I’m going for simplicity, so I’m using whatever WordPress defaults for me (55 words stripped of HTML).

The more tag is actually typed out in your WordPress post, so you actually have to (or can) figure where exactly you want the break to be. More control, less automation. It looks like this <!--More-->

The entire if statement is in the main WordPress loop. The is_category() and is_archive() functions should be self-explanatory. The third condition is a little complicated…

What I want is to customise the layout of the home page. The home page is neither a single WordPress post nor a WordPress page, hence the !is_single() and !is_page(). The $postcounter variable is used to keep track of how many posts were already displayed. The declaration and incrementation of the variable is not shown in the code.

The desired effect is that, on the home page, only the first post (which is the latest) is displayed in full. All other posts on the home page is displayed in excerpt form.

In the else part, it should be either a single post or page, so display the full content. The function the_content() takes a single parameter which is the “read more” text.

I have a customised version of the_content() parameter, which I believe will use any localisation files to translate the given text. If you’re not concerned with it, just use something like the_content('Read more...');.

Hope this helped you in some way.

P.S. Currently, I use 5 posts per display page. If I go to the second display page on my home page, the first post (the 6th post) displayed is in full, whereas the rest are in excerpt form. It’s not a critical issue, so I’m letting it be…

1 August, 2008 | Written by Vincent Tan Leave a Comment

Be careful when timing one-liners

Be careful when differences between your timing tests are one-liners, and these one-liners are the entirety of your timing code. This applies to small chunks of code too. I’m actually extending a remark I said while discussing multiplications, additions and bit shifts:

This allows you to increase the percentage of identical parts between the tests, and thus highlight the difference in only the calculation method

The small code chunks you’re testing are sensitive to timing, meaning their timing results are likely to fluctuate. Instead of testing the code chunks in isolation, surround them in code used in a typical situation. Why should you do this?

Suppose you’re testing 2 methods. In isolation, method A took 2 seconds. Method B took 5 seconds. Wow! Hands down, method A is faster than method B.

Then when you use method A in production, you find no real speed benefit. Why?

Because in a typical use situation, the surrounding code together with method A takes 60 seconds. A 3 second savings isn’t much. In reality, it doesn’t matter which method you use. Practically speaking, they took the same amount of time.

This was what I meant by increasing the percentage of identical parts.

A physics experiment: timing falling balls

Suppose you want to time how fast a ball falls from a specific height to reach the ground. You start with experiment A (shown in picture), with a low height.

Timing falling balls

Then you try starting from a higher height, say 3 times higher, in experiment B. You take your measurements and do the relevant calculations. Taking into account the different heights, you divide the timings in experiment B by 3 to normalise them with those of experiment A. And you find they differ quite a bit. Why?

Because you forgot to take into account that when you start and stop a timer, your reaction time comes into play.

Your reaction time took a larger percentage in the total time taken in experiment A because the ball hits the ground fairly fast. In experiment B, the time taken to hit the ground is longer, so your reaction time takes a smaller percentage.

So what’s the larger “percentage of identical parts” in experiment B? Air, or more height.*

* assuming wind and air eddies don’t foul up the experiment

30 July, 2008 | Written by Vincent Tan 3 Comments

Can you make small changes in an unknown language?

If you’re tasked to make minor changes to an existing program in a programming language that you’ve never used before, can you do it? Consider the following fictitious interview question:

You’re writing code in a programming language that you’ve never used before. You have no documentation about the language except the other code. Complete the following function: …

Let’s make this easier. Can you do it if you’re only slightly unfamiliar with the programming language?

When I learned new programming languages, I looked for how to:

  • declare and initialise variables
  • do loops (such as for and while in the C family)
  • do conditionals (the if statement)
  • do multi-conditionals (switch for C#, select case for VB.NET) if available
  • take in input and print output
  • write and use functions

You might have a different list, and that’s ok. It’s how I look for patterns.

With that in mind, if you had sufficient lines of code, you should be able to figure out what the code did. Even if you’ve never seen the programming language before. Then you could make the minor changes you’re tasked with some level of confidence.

It’s not like you code in assembly, right? … Are you?

I don’t have a code sample to show you. Alright fine, I’m too lazy to think up one… Do you have something to show? Post in the comments, and I’ll rack my brains on it…

18 July, 2008 | Written by Vincent Tan Leave a Comment

Multiplications, additions and bit shifts

In a previous article, I asked what this does

int foo(int para)
{
	int temp = para << 3;
	return temp + temp + temp;
}

The function basically returns a value of the parameter multiplied by 24 (thanks Mark!).

So why was it written that way? Speed.

From what I understand, in the olden days, multiplication was slower than addition and bit shift operations. I don’t know how slow, but it was slow. It was so slow that programmers (particularly game programmers) started replacing multiplication operations with a combination of additions and bit shifts.

Our example above with 1 bit shift and 2 additions was faster than just 1 multiplication operation. Hmm… that example may not be the best to use… Let me give another one.

The idea is to split the multiplication into additions first. So
i * 80
becomes
i * (64 + 16)
which becomes
(i * 64) + (i * 16)
which becomes
(i << 6) + (i << 4)
where we swap multiplications with powers of 2 to bit shifts. See, you do need some math in game programming.

Bit shifts are faster than additions, which are faster than multiplications. The speed difference obtained from rewriting the code was enough for some game programmers to adopt for use.

With modern computer chips, multiplications are just as fast as additions and bit shifts. So I did some comparison. Before I show you the code, there are 2 warnings:

  • The code segments aren’t supposed to be tested on their own. The original speed improvements made sense when combined with their surrounding code.
  • Measuring something changes it, so you’re not measuring the true value (some principle from physics. If you can find me a reference, I’d appreciate it).

I will present 4 different ways of multiplying by 24 using 4 functions. The first is the one posed in the previous post:

int foo(int para)
{
    int temp = para << 3;
    return temp + temp + temp;
}

The second function uses multiplication.

int goo(int para)
{
    int temp = para;
    return temp * 24;
}

I didn’t really have to declare the variable temp. I did it so all 4 functions declare a variable. Even variable declaration takes time, minute as it is, so I had to take that into account and standardise it across the 4 functions. This is the part where “measuring something changes it”…

The third function uses 2 bit shifts and 1 addition.

int hoo(int para)
{
    int temp = para;
    return (temp << 4) + (temp << 3);
}

Convince yourself that the return value is a multiplication of the parameter by 24.

The fourth function is a modification of the first function.

int loo(int para)
{
    int temp = para << 3;
    return (temp << 1) + temp;
}

If bit shifts are faster than additions, temp << 1 is faster than temp + temp, right? The use of temporary variables to hold intermediate values for another calculation is another technique used in game programming. This sounds a little vague, so I’m publishing another article to explain this further.

And here’s the timing code

const int cnMax = 500000000;
const int cnLoops = 20;
const int cnValue = 5;
DateTime dtStart = DateTime.Now;
DateTime dtEnd = DateTime.Now;
TimeSpan ts;
int i, j, temp = 0;

temp = 0;
dtStart = DateTime.Now;
for (i = 0; i < cnLoops; ++i)
{
    for (j = 0; j < cnMax; ++j)
    {
        temp = foo(cnValue);
    }
}
dtEnd = DateTime.Now;
ts = dtEnd - dtStart;
Console.WriteLine(ts.TotalSeconds);
Console.WriteLine(temp);

temp = 0;
dtStart = DateTime.Now;
for (i = 0; i < cnLoops; ++i)
{
    for (j = 0; j < cnMax; ++j)
    {
        temp = goo(cnValue);
    }
}
dtEnd = DateTime.Now;
ts = dtEnd - dtStart;
Console.WriteLine(ts.TotalSeconds);
Console.WriteLine(temp);

temp = 0;
dtStart = DateTime.Now;
for (i = 0; i < cnLoops; ++i)
{
    for (j = 0; j < cnMax; ++j)
    {
        temp = hoo(cnValue);
    }
}
dtEnd = DateTime.Now;
ts = dtEnd - dtStart;
Console.WriteLine(ts.TotalSeconds);
Console.WriteLine(temp);

temp = 0;
dtStart = DateTime.Now;
for (i = 0; i < cnLoops; ++i)
{
    for (j = 0; j < cnMax; ++j)
    {
        temp = loo(cnValue);
    }
}
dtEnd = DateTime.Now;
ts = dtEnd - dtStart;
Console.WriteLine(ts.TotalSeconds);
Console.WriteLine(temp);

I’ve initialised temp to 0 just before the test loops, and printed its value after the loops to check that the calculations give correct results. The loops are coded with a standard structure, and the only difference is the function used. All 4 functions are coded in as similar a structure as possible, to isolate only the method of calculation.

I’ve used nested for loops to increase the number of iterations. One loop can only go as high as 2^31 iterations (unless I use long). Nested loops increase this limit by doing a lower iteration limit multiple times.

And the conclusion? Multiplications are now just as fast. I didn’t get consistent results to rank the methods in order of speed though. Generally speaking, the 2-shift-1-add method (3rd function) is faster than multiply-by-24 method (2nd function).

That’s it. As an exercise, you might want to come up with better code to time them. Follow some simple rules:

  • The results must be repeatable
  • Tests must be standardised

A suggestion? Perhaps you can add more code to the loop structure (or the functions). So long as all 4 loops (or function code) are similar, you don’t need a minimalistic approach. This allows you to increase the percentage of identical parts between the tests, and thus highlight the difference in only the calculation method (let me know if you’re confused by this).

Have fun!

17 July, 2008 | Written by Vincent Tan 1 Comment

Translating database column names for globalisation

I was working at a software development house where one of those enterprisey .NET web applications was created for a large company. It was fairly standard. There were workflow processes, inventory tracking business logic, user management and the like.

The web application also had to display information in both English and Japanese (the customer was, you know, a Japanese company).

While the database column names were in English, there must be an option to display the Japanese equivalent. Suppose we had a table scripted like:

create table staff
(
STF_ID nchar(10) not null,
STF_NAME nvarchar(100) not null,
EFF_DT datetime not null
)

When I was creating datasets, I used Pascal case as recommended, and typed out words in full. So I had something like

ds.StaffID = "FIRSTID";
ds.StaffName = "Some name";
ds.EffectiveDate = DateTime.UtcNow;

The lead developer gently asked me why I coded that way. I explained the recommended practices for variable naming. I was actually quite puffed up with pride because of that knowledge.

The lead developer said he understood (though I didn’t think he did). Then he gave me an explanation why my method was a bad idea. He said translations for English and Japanese were based on resource files, and the contents of those files were based on the names used in the database tables.

So in the resource file, there would be an entry for STF_ID to be translated into “Staff ID” in English and “sutafu ID” in Japanese.

Staff ID translation (English and Japanese)

If I used “ds.StaffID”, it would be confusing for other programmers because I did some “translating” on my own. Someone else might translate differently and soon, the whole project would go up in flames. A standard way of referring to the database column name was established, and that was whatever the column name was originally. Even if it doesn’t look quite right in code.

So there would be

ds.STF_ID = "ID09183";
ds.STF_NAME = "another robot";
ds.EFF_DT = DateTime.UtcNow;

After some thinking, I had to concede. Using the database column name in code did make sense. There were full-time people hired to enter a code, word or phrase with the English and Japanese equivalent into the resource files. There were many developers working on that project. It’s just more efficient to use the column names as a standard.

That said, there’s much to be desired for the variable naming skills of the database administrators…

← Previous PageNext Page →