| wa ws ba bs bc wc n |
ba := (120 to: 125) collect: [:cc| Character value: cc].
bs := ba asString.
bc := ba last.
wa := (12345 to: 12350) collect: [:cc| Character value: cc].
ws := wa asString.
wc := wa last.
n := 1000000.
{ Time millisecondsToRun: [1 to: n do: [:ign| ba identityIndexOf: bc ifAbsent: 0]].
Time millisecondsToRun: [1 to: n do: [:ign| bs identityIndexOf: bc ifAbsent: 0]].
Time millisecondsToRun: [1 to: n do: [:ign| wa identityIndexOf: wc ifAbsent: 0]].
Time millisecondsToRun: [1 to: n do: [:ign| ws identityIndexOf: wc ifAbsent: 0]] }
Squeak 4.0 beta1 Closure: #(448 1058 451 8631)
Stack VM: #(581 1531 579 7303)
Cog: #(214 600 213 1970)
So string access is two to three times slower than array access when the result is fetched from the character table and an order of magnitude worse when the result must be boxed. (I don't know why the Stack VM is slower than Squeak 4 for non-boxed access; I probably need to do a merge :) ).