ואוו, צודק, שכחתי בכלל לבדוק במחרוזת ארוכה, הממ, גם לי זה מוזר - הייתי מצפה שבמחרוזת ארוכה, דווקא השיטה שלי תיהיה מהירה יותר ושלך איטית יותר - הרי אתה עובר על כל תו בטקסט.. 
שים לב שהפונקציה שלך איטית יותר ככל שצריך לחתוך יותר מילים(=יותר טקסט לעבור).... הממ, טוב, חוץ משיפור קטן שאפשר לעשות בפונקציה שלך(לפי דעתי להפוך את ה-for ל-do_while, ואת ה-$count++ אל ++$count(כאשר ה-++ לפני המשתנה), גם כדאי לך להפוך את ה-$count < $num וה-$i < $len (להפוך את המיקום שלהם) כי רוב הסיכויים שהעניין של $count יחזיר FALSE לפני $i.
עכשיו, במקום $len אתה יכול להשתמש ב-isset. 
טיפה עבדתי על זה - עדיין יש כמה נקודות לשיפור, אבל,
	PHP קוד:
	
		
			
function getWords ($str, $num, $separator = ' ', $validation = true)
{
    if ($validation) {
        if (! is_int($num)) {
            trigger_error('function: getWords(). $num is not an integer.', E_USER_ERROR);
            return false;
        }
        if (!is_string($str)) {
            trigger_error('function: getWords(). $str is not a string.', E_USER_ERROR);
            return false;
        }
        if (!is_string($separator)) {
            trigger_error('function: getWords(). $separator is not a string.', E_USER_ERROR);
            return false;
        }
    }
    $count = 0;
    $i = 0;
    do {
        if ($str[$i] == $separator)
            ++$count;
        ++$i;
    } while (isset($str[$i]) && $count < $num);
    return substr($str, 0, $i);
} 
		
	
 מבוססת על הרעיון שלך.
הכנתי עוד פונקציה שמשתמשת בעיקרון ה-offSet של strpos
	PHP קוד:
	
		
			
function getWordsb ($str, $num, $separator = ' ', $validation = true)
{
    if (!is_bool($validation)) {
        trigger_error('function: getWords(). $validation is not a boolean.', E_USER_ERROR);
        return false;
    }
    if ($validation) {
        if (! is_int($num)) {
            trigger_error('function: getWords(). $num is not an integer.', E_USER_ERROR);
            return false;
        }
        if (!is_string($str)) {
            trigger_error('function: getWords(). $str is not a string.', E_USER_ERROR);
            return false;
        }
        if (!is_string($separator)) {
            trigger_error('function: getWords(). $separator is not a string.', E_USER_ERROR);
            return false;
        }
    }
    $count = 0;
    $offset = 0;
    while (($offset = strpos($str, $separator, $offset)) !== false && $count < $num) {
        if ($str[$offset] == $separator)
            ++$count;
    }
    return substr($str, 0, $offset);
} 
		
	
 אבל גם היא, לא מהירה יותר יחסית לפונקציה שציינתי מעל.