Parcourir la source

perf(processor): avoid per-char string allocation in parseISO8601Duration

Replace `num += string(char)` with index-based slicing of the input
string. The previous loop allocated a new string for every digit in
the duration (and again on each `+=`), giving O(n²) allocation
behavior. Slicing `after[start:i]` reuses the original string's
backing memory and only allocates once per numeric component when
passed to `strconv.Atoi`.

It also makes the code a bit more compact/simpler.

Called once per YouTube/podcast entry that exposes an ISO8601
duration during feed processing.
jvoisin il y a 1 semaine
Parent
commit
c2661ca1c4
1 fichiers modifiés avec 15 ajouts et 22 suppressions
  1. 15 22
      internal/reader/processor/utils.go

+ 15 - 22
internal/reader/processor/utils.go

@@ -36,39 +36,32 @@ func parseISO8601Duration(duration string) (time.Duration, error) {
 	}
 
 	var d time.Duration
-	num := ""
+	start := 0
 
-	for _, char := range after {
-		var val int
-		var err error
+	for i := 0; i < len(after); i++ {
+		var unit time.Duration
 
-		switch char {
+		switch after[i] {
 		case 'Y', 'W', 'D':
-			return 0, fmt.Errorf("the '%c' specifier isn't supported", char)
+			return 0, fmt.Errorf("the '%c' specifier isn't supported", after[i])
 		case 'H':
-			if val, err = strconv.Atoi(num); err != nil {
-				return 0, err
-			}
-			d += time.Duration(val) * time.Hour
-			num = ""
+			unit = time.Hour
 		case 'M':
-			if val, err = strconv.Atoi(num); err != nil {
-				return 0, err
-			}
-			d += time.Duration(val) * time.Minute
-			num = ""
+			unit = time.Minute
 		case 'S':
-			if val, err = strconv.Atoi(num); err != nil {
-				return 0, err
-			}
-			d += time.Duration(val) * time.Second
-			num = ""
+			unit = time.Second
 		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
-			num += string(char)
 			continue
 		default:
 			return 0, errors.New("invalid character in the period")
 		}
+
+		val, err := strconv.Atoi(after[start:i])
+		if err != nil {
+			return 0, err
+		}
+		d += time.Duration(val) * unit
+		start = i + 1
 	}
 	return d, nil
 }