Skip to content

Commit

Permalink
String: some optimizations when ascii only
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite committed Nov 22, 2016
1 parent d599667 commit f5d54f4
Showing 1 changed file with 56 additions and 17 deletions.
73 changes: 56 additions & 17 deletions src/string.cr
Expand Up @@ -875,10 +875,21 @@ class String
# "hEllO".downcase # => "hello"
# ```
def downcase(options = Unicode::CaseOptions::None)
String.build(bytesize) do |io|
each_char do |char|
char.downcase(options) do |res|
io << res
return self if empty?

if ascii_only?

This comment has been minimized.

Copy link
@RX14

RX14 Nov 22, 2016

Contributor

Maybe document the assumption that the case options won't have an effect on ascii characters?

This comment has been minimized.

Copy link
@asterite

asterite Nov 22, 2016

Author Member

Oops... this change is actually wrong, I shouldn't have done it so quickly. The problem is that this now works in a wrong way:

"aeiou".upcase(Unicode::CaseOptions::Turkic) # => "AEIOU"

This comment has been minimized.

Copy link
@asterite

asterite Nov 22, 2016

Author Member
String.new(bytesize) do |buffer|
bytesize.times do |i|
buffer[i] = to_unsafe[i].unsafe_chr.downcase.ord.to_u8
end
{@bytesize, @length}
end
else
String.build(bytesize) do |io|
each_char do |char|
char.downcase(options) do |res|
io << res
end
end
end
end
Expand All @@ -891,10 +902,21 @@ class String
# "hEllO".upcase # => "HELLO"
# ```
def upcase(options = Unicode::CaseOptions::None)
String.build(bytesize) do |io|
each_char do |char|
char.upcase(options) do |res|
io << res
return self if empty?

if ascii_only?
String.new(bytesize) do |buffer|
bytesize.times do |i|
buffer[i] = to_unsafe[i].unsafe_chr.upcase.ord.to_u8
end
{@bytesize, @length}
end
else
String.build(bytesize) do |io|
each_char do |char|
char.upcase(options) do |res|
io << res
end
end
end
end
Expand All @@ -907,14 +929,27 @@ class String
# "hEllO".capitalize # => "Hello"
# ```
def capitalize

This comment has been minimized.

Copy link
@RX14

RX14 Nov 22, 2016

Contributor

We probably want case options here too.

This comment has been minimized.

Copy link
@asterite

asterite Nov 22, 2016

Author Member

Yup! Thought the same so I just did :-)

return self if bytesize == 0
return self if empty?

String.build(bytesize) do |io|
each_char_with_index do |char, i|
if i == 0
char.upcase { |c| io << c }
else
char.downcase { |c| io << c }
if ascii_only?
String.new(bytesize) do |buffer|
bytesize.times do |i|
if i == 0
buffer[i] = to_unsafe[i].unsafe_chr.upcase.ord.to_u8
else
buffer[i] = to_unsafe[i].unsafe_chr.downcase.ord.to_u8
end
end
{@bytesize, @length}
end
else
String.build(bytesize) do |io|
each_char_with_index do |char, i|
if i == 0
char.upcase { |c| io << c }
else
char.downcase { |c| io << c }
end
end
end
end
Expand All @@ -933,7 +968,7 @@ class String
#
# See also: `#chop`
def chomp
return self if bytesize == 0
return self if empty?

case to_unsafe[bytesize - 1]
when '\n'
Expand Down Expand Up @@ -2725,6 +2760,8 @@ class String
# "eiffel_tower".camelcase # => "EiffelTower"
# ```
def camelcase
return self if empty?

first = true
last_is_underscore = false

Expand Down Expand Up @@ -2752,6 +2789,8 @@ class String
# "racecar".reverse # => "racecar"
# ```
def reverse
return self if bytesize <= 1

if ascii_only?
String.new(bytesize) do |buffer|
bytesize.times do |i|
Expand Down Expand Up @@ -2844,7 +2883,7 @@ class String
# "***".succ # => "**+"
# ```
def succ
return self if bytesize == 0
return self if empty?

chars = self.chars

Expand Down

0 comments on commit f5d54f4

Please sign in to comment.