Thanks for the feedback.  at() didn't seem to do much, but I just remembered 
the glCallLists() trick:

def draw_string( string )
   GL::Enable( GL::TEXTURE_2D )
     GL::CallLists( string )
   GL::Disable( GL::TEXTURE_2D )
end

Oh yea :)
Mike

George Ogata wrote:
> Mike Austin <noone / nowhere.com> writes:
> 
>> I decided it was time to do a little profiling, and am so glad that
>> it's built right into Ruby.  My biggest problem seems to be array
>> access:
>>
>>   %   cumulative   self              self     total
>> time   seconds   seconds    calls  ms/call  ms/call  name
>> 36.02     3.35      3.35      350     9.57    15.10  String#each_byte
>> 10.45     4.32      0.97    27230     0.04     0.04  Array#[]
>>   6.73     4.95      0.63    16100     0.04     0.04  GL.Vertex
>>
>> I'll eventually go to display-lists or similar in OpenGL, but I was
>> wondering if I could optimize this any further?
>>
>> def draw_string( string )
>>    size = font.height
>>    x = 0
>>
>>    GL::Enable( GL::TEXTURE_2D )
>>    GL::Begin( GL::QUADS )
>>    string.each_byte do |char|
>>      offset = char - 32
>>      GL::TexCoord2f( @tex_coords_left[offset], @tex_coords_top[offset] );
>>      GL::Vertex(        x,    0 )
>>      GL::TexCoord2f( @tex_coords_left[offset], @tex_coords_bottom[offset] );
>>      GL::Vertex(        x, size )
>>      GL::TexCoord2f( @tex_coords_right[offset], @tex_coords_bottom[offset] );
>>      GL::Vertex( x + size, size )
>>      GL::TexCoord2f( @tex_coords_right[offset], @tex_coords_top[offset] );
>>      GL::Vertex( x + size,    0 )
>>      x += @sizes[char-32][0]
>>    end
>>    GL::End()
>>    GL::Disable( GL::TEXTURE_2D )
>> end
> 
> Perhaps use #at instead of #[] ?  Using texture coord arrays might
> help too.  But if that's really only 10% of the total time, I don't
> think it's going to make too much difference...