Просмотр исходного кода

perf(reader): preallocate some slices/maps

4 to 1, with a meaningful ns/op win on hot feed-parse paths. personNames trades
a slightly larger fixed allocation for fewer growths and gets ~29% faster.
The micro-benchmarks used to obtain those numbers are, well, micro-benchmarks,
and thus I don't think it would make sense to add them to miniflux.
jvoisin 1 месяц назад
Родитель
Сommit
55821b9fba
2 измененных файлов с 18 добавлено и 12 удалено
  1. 2 2
      internal/reader/atom/atom_common.go
  2. 16 10
      internal/reader/rss/adapter.go

+ 2 - 2
internal/reader/atom/atom_common.go

@@ -33,8 +33,8 @@ func (a *AtomPerson) PersonName() string {
 type atomPersons []*AtomPerson
 
 func (a atomPersons) personNames() []string {
-	var names []string
-	authorNamesMap := make(map[string]bool)
+	names := make([]string, 0, len(a))
+	authorNamesMap := make(map[string]bool, len(a))
 
 	for _, person := range a {
 		personName := person.PersonName()

+ 16 - 10
internal/reader/rss/adapter.go

@@ -181,7 +181,8 @@ func findFeedAuthor(rssChannel *rssChannel) string {
 }
 
 func findFeedTags(rssChannel *rssChannel) []string {
-	tags := make([]string, 0)
+	itunesCategories := rssChannel.GetItunesCategories()
+	tags := make([]string, 0, len(rssChannel.Categories)+len(itunesCategories)+1)
 
 	for _, tag := range rssChannel.Categories {
 		tag = strings.TrimSpace(tag)
@@ -190,7 +191,7 @@ func findFeedTags(rssChannel *rssChannel) []string {
 		}
 	}
 
-	for _, tag := range rssChannel.GetItunesCategories() {
+	for _, tag := range itunesCategories {
 		tag = strings.TrimSpace(tag)
 		if tag != "" {
 			tags = append(tags, tag)
@@ -299,7 +300,8 @@ func findEntryAuthor(rssItem *rssItem) string {
 }
 
 func findEntryTags(rssItem *rssItem) []string {
-	tags := make([]string, 0)
+	mediaLabels := rssItem.MediaCategories.Labels()
+	tags := make([]string, 0, len(rssItem.Categories)+len(mediaLabels))
 
 	for _, tag := range rssItem.Categories {
 		tag = strings.TrimSpace(tag)
@@ -308,7 +310,7 @@ func findEntryTags(rssItem *rssItem) []string {
 		}
 	}
 
-	for _, tag := range rssItem.MediaCategories.Labels() {
+	for _, tag := range mediaLabels {
 		tag = strings.TrimSpace(tag)
 		if tag != "" {
 			tags = append(tags, tag)
@@ -319,10 +321,14 @@ func findEntryTags(rssItem *rssItem) []string {
 }
 
 func findEntryEnclosures(rssItem *rssItem, siteURL string) model.EnclosureList {
-	enclosures := make(model.EnclosureList, 0)
-	duplicates := make(map[string]bool)
-
-	for _, mediaThumbnail := range rssItem.AllMediaThumbnails() {
+	mediaThumbnails := rssItem.AllMediaThumbnails()
+	mediaContents := rssItem.AllMediaContents()
+	mediaPeerLinks := rssItem.AllMediaPeerLinks()
+	capacity := len(mediaThumbnails) + len(rssItem.Enclosures) + len(mediaContents) + len(mediaPeerLinks)
+	enclosures := make(model.EnclosureList, 0, capacity)
+	duplicates := make(map[string]bool, capacity)
+
+	for _, mediaThumbnail := range mediaThumbnails {
 		mediaURL := strings.TrimSpace(mediaThumbnail.URL)
 		if mediaURL == "" {
 			continue
@@ -375,7 +381,7 @@ func findEntryEnclosures(rssItem *rssItem, siteURL string) model.EnclosureList {
 		}
 	}
 
-	for _, mediaContent := range rssItem.AllMediaContents() {
+	for _, mediaContent := range mediaContents {
 		mediaURL := strings.TrimSpace(mediaContent.URL)
 		if mediaURL == "" {
 			continue
@@ -399,7 +405,7 @@ func findEntryEnclosures(rssItem *rssItem, siteURL string) model.EnclosureList {
 		}
 	}
 
-	for _, mediaPeerLink := range rssItem.AllMediaPeerLinks() {
+	for _, mediaPeerLink := range mediaPeerLinks {
 		mediaURL := strings.TrimSpace(mediaPeerLink.URL)
 		if mediaURL == "" {
 			continue