From 386688aa9f1cb636e7694bf04b30466421822663 Mon Sep 17 00:00:00 2001 From: Adam Shannon Date: Wed, 27 Mar 2024 14:16:24 -0500 Subject: [PATCH] perf: improve includesValidCharacters lookups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MergeFiles/MergeFiles-16 942.8µ ± ∞ ¹ 505.5µ ± ∞ ¹ ~ (p=1.000 n=1) ² MergeFiles/MergeFiles_ValidateOpts-16 958.8µ ± ∞ ¹ 503.0µ ± ∞ ¹ ~ (p=1.000 n=1) ² geomean 1.105m 535.8µ -51.50% MergeFiles/MergeFiles-16 55.71Ki ± ∞ ¹ 55.60Ki ± ∞ ¹ ~ (p=1.000 n=1) ² MergeFiles/MergeFiles_ValidateOpts-16 55.69Ki ± ∞ ¹ 55.62Ki ± ∞ ¹ ~ (p=1.000 n=1) ² geomean 57.61Ki 57.43Ki -0.33% MergeFiles/MergeFiles-16 637.0 ± ∞ ¹ 637.0 ± ∞ ¹ ~ (p=1.000 n=1) ² MergeFiles/MergeFiles_ValidateOpts-16 637.0 ± ∞ ¹ 637.0 ± ∞ ¹ ~ (p=1.000 n=1) ² geomean 656.7 656.4 -0.05% --- validators.go | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/validators.go b/validators.go index c398b5145..7eec901f8 100644 --- a/validators.go +++ b/validators.go @@ -34,10 +34,20 @@ var ( asciiCharacters = ` !"#$%&'()*+,-./:;<=>?@[\]^_{|}~` + "`" ebcdicExtraCharacters = `¢¬¦±` - validAlphaNumericCharacters = lowerAlphaCharacters + strings.ToUpper(lowerAlphaCharacters) + numericCharacters + asciiCharacters + ebcdicExtraCharacters - validUppercaseAlphaNumericCharacters = strings.ToUpper(lowerAlphaCharacters) + numericCharacters + asciiCharacters + ebcdicExtraCharacters + validAlphaNumericCharacters map[rune]bool + validUppercaseAlphaNumericCharacters map[rune]bool ) +func init() { + validAlphaNumericCharacters = setupCharacterMap( + lowerAlphaCharacters, strings.ToUpper(lowerAlphaCharacters), numericCharacters, asciiCharacters, ebcdicExtraCharacters, + ) + + validUppercaseAlphaNumericCharacters = setupCharacterMap( + strings.ToUpper(lowerAlphaCharacters), numericCharacters, asciiCharacters, ebcdicExtraCharacters, + ) +} + // validator is common validation and formatting of golang types to ach type strings type validator struct{} @@ -425,15 +435,19 @@ func (v *validator) isTransactionTypeCode(s string) error { return ErrTransactionTypeCode } -func (v *validator) includesValidCharacters(input string, charset string) error { - for _, i := range input { - var found bool - for _, c := range charset { - if i == c { - found = true - break - } +func setupCharacterMap(inputs ...string) map[rune]bool { + out := make(map[rune]bool) + for _, input := range inputs { + for _, r := range input { + out[r] = true } + } + return out +} + +func (v *validator) includesValidCharacters(input string, charset map[rune]bool) error { + for _, i := range input { + _, found := charset[i] if !found { return fmt.Errorf("invalid character: %v", i) }