protoregistry: avoid checking for '/' in FindMessageByName

Profiling shows FindMessageByName spending considerable time
in strings.LastIndexByte in FindMessageByURL.

This overhead can be avoided by giving FindMessageByName
its own implementation not pruning the name string up
to the last '/' which can not appear in a protobuf name.

Change-Id: Ifec07689f72790ead8b7552cd04dd99fa67b61e4
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/240378
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/reflect/protoregistry/registry.go b/reflect/protoregistry/registry.go
index 7dcf4d9..be26105 100644
--- a/reflect/protoregistry/registry.go
+++ b/reflect/protoregistry/registry.go
@@ -562,13 +562,25 @@
 	return nil, NotFound
 }
 
-// FindMessageByName looks up a message by its full name.
-// E.g., "google.protobuf.Any"
+// FindMessageByName looks up a message by its full name,
+// e.g. "google.protobuf.Any".
 //
-// This return (nil, NotFound) if not found.
+// This returns (nil, NotFound) if not found.
 func (r *Types) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) {
-	// The full name by itself is a valid URL.
-	return r.FindMessageByURL(string(message))
+	if r == nil {
+		return nil, NotFound
+	}
+	if r == GlobalTypes {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	if v := r.typesByName[message]; v != nil {
+		if mt, _ := v.(protoreflect.MessageType); mt != nil {
+			return mt, nil
+		}
+		return nil, errors.New("found wrong type: got %v, want message", typeName(v))
+	}
+	return nil, NotFound
 }
 
 // FindMessageByURL looks up a message by a URL identifier.
@@ -576,6 +588,8 @@
 //
 // This returns (nil, NotFound) if not found.
 func (r *Types) FindMessageByURL(url string) (protoreflect.MessageType, error) {
+	// This function is similar to FindMessageByName but
+	// truncates anything before and including '/' in the URL.
 	if r == nil {
 		return nil, NotFound
 	}