Thank you Jeff, I was too sleepy to run comparison tests myself last night.
Your input length condition is a nice touch.
But no Jeff, it not a cross-join nor generates 65,536 internal rows. It's a n inner join. You can see it if you check out its execution plan, and it can be replaced with:
----------------------------------------
select @output = @output + char(b.dec)
from dec2hex a inner join dec2hex b
on b.hex = substring(@input,a.dec*2+1,2)
where a.dec*2+1 < LEN(@input)
order by a.dec
----------------------------------------
without affecting its semantics at all.
And dec2hex table is looked-up just LEN(@output) times.(It was 256 times before you add the criteria, though.)
I think it's weird that Richard's function is still much faster. I thought the join routine of the server should be most efficient. Moreover, my function calls substring() half the times of Richard's.
Anyway, it was a very interesting quiz. Thank you all!