}
 
 // ToUpper returns a copy of the string s with all Unicode letters mapped to their upper case.
-func ToUpper(s string) string { return Map(unicode.ToUpper, s) }
+func ToUpper(s string) string {
+       isASCII, hasLower := true, false
+       for i := 0; i < len(s); i++ {
+               c := s[i]
+               if c >= utf8.RuneSelf {
+                       isASCII = false
+                       break
+               }
+               hasLower = hasLower || (c >= 'a' && c <= 'z')
+       }
+
+       if isASCII { // optimize for ASCII-only strings.
+               if !hasLower {
+                       return s
+               }
+               b := make([]byte, len(s))
+               for i := 0; i < len(s); i++ {
+                       c := s[i]
+                       if c >= 'a' && c <= 'z' {
+                               c -= 'a' - 'A'
+                       }
+                       b[i] = c
+               }
+               return string(b)
+       }
+       return Map(unicode.ToUpper, s)
+}
 
 // ToLower returns a copy of the string s with all Unicode letters mapped to their lower case.
 func ToLower(s string) string { return Map(unicode.ToLower, s) }
 
 
 var upperTests = []StringTest{
        {"", ""},
+       {"ONLYUPPER", "ONLYUPPER"},
        {"abc", "ABC"},
        {"AbC123", "ABC123"},
        {"azAZ09_", "AZAZ09_"},
+       {"longStrinGwitHmixofsmaLLandcAps", "LONGSTRINGWITHMIXOFSMALLANDCAPS"},
+       {"long\u0250string\u0250with\u0250nonascii\u2C6Fchars", "LONG\u2C6FSTRING\u2C6FWITH\u2C6FNONASCII\u2C6FCHARS"},
        {"\u0250\u0250\u0250\u0250\u0250", "\u2C6F\u2C6F\u2C6F\u2C6F\u2C6F"}, // grows one byte per char
 }
 
 
 func TestToLower(t *testing.T) { runStringTests(t, ToLower, "ToLower", lowerTests) }
 
+func BenchmarkToUpper(b *testing.B) {
+       for _, tc := range upperTests {
+               b.Run(tc.in, func(b *testing.B) {
+                       for i := 0; i < b.N; i++ {
+                               actual := ToUpper(tc.in)
+                               if actual != tc.out {
+                                       b.Errorf("ToUpper(%q) = %q; want %q", tc.in, actual, tc.out)
+                               }
+                       }
+               })
+       }
+}
+
 func BenchmarkMapNoChanges(b *testing.B) {
        identity := func(r rune) rune {
                return r