From d0ceaf7a7a3e6ca6bf990f516d16f9161141d540 Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Wed, 22 Sep 2021 08:49:42 -0700 Subject: [PATCH] [fenix] For https://github.com/mozilla-mobile/fenix/issues/21294: remove allocations in Fact.toEvent. This commit was generated primarily by a macro that: - appends `== component &&` - appends `== item` - (if applicable) Skips to the ending brace - Go down one line and move cursor to the front of the line to prep for repeat My only intervention was to skip extra lines to line it up to run again and specify how many times in a row it should run. --- The `to` in this code is an infix function that calls instantiates a Pair under the hood. Subjectively observed, when this method is called it generally hits the else case so 35 Pairs are instantiated each call - that's 560 bytes. This method is called frequently - for example, an estimated 4 times each time a letter is typed on the homescreen and a measured 116 times in a simple navigation (see the issue). The latter generates an estimated 63.4 KiB. It was straightforward to remove these allocations so that's what this change does. The primary risk from this change is that it's difficult to test each case to ensure it's working. --- .../components/metrics/MetricController.kt | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt index d7e7566665..b1975d2508 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt @@ -159,25 +159,25 @@ internal class ReleaseMetricController( @Suppress("LongMethod") private fun Fact.toEvent(): Event? = when { - Component.FEATURE_PROMPTS to LoginDialogFacts.Items.DISPLAY -> Event.LoginDialogPromptDisplayed - Component.FEATURE_PROMPTS to LoginDialogFacts.Items.CANCEL -> Event.LoginDialogPromptCancelled - Component.FEATURE_PROMPTS to LoginDialogFacts.Items.NEVER_SAVE -> Event.LoginDialogPromptNeverSave - Component.FEATURE_PROMPTS to LoginDialogFacts.Items.SAVE -> Event.LoginDialogPromptSave - Component.FEATURE_PROMPTS to CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_FORM_DETECTED -> + Component.FEATURE_PROMPTS == component && LoginDialogFacts.Items.DISPLAY == item -> Event.LoginDialogPromptDisplayed + Component.FEATURE_PROMPTS == component && LoginDialogFacts.Items.CANCEL == item -> Event.LoginDialogPromptCancelled + Component.FEATURE_PROMPTS == component && LoginDialogFacts.Items.NEVER_SAVE == item -> Event.LoginDialogPromptNeverSave + Component.FEATURE_PROMPTS == component && LoginDialogFacts.Items.SAVE == item -> Event.LoginDialogPromptSave + Component.FEATURE_PROMPTS == component && CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_FORM_DETECTED == item -> Event.CreditCardFormDetected - Component.FEATURE_PROMPTS to CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_SUCCESS -> + Component.FEATURE_PROMPTS == component && CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_SUCCESS == item -> Event.CreditCardAutofilled - Component.FEATURE_PROMPTS to CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_PROMPT_SHOWN -> + Component.FEATURE_PROMPTS == component && CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_PROMPT_SHOWN == item -> Event.CreditCardAutofillPromptShown - Component.FEATURE_PROMPTS to CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_PROMPT_EXPANDED -> + Component.FEATURE_PROMPTS == component && CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_PROMPT_EXPANDED == item -> Event.CreditCardAutofillPromptExpanded - Component.FEATURE_PROMPTS to CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_PROMPT_DISMISSED -> + Component.FEATURE_PROMPTS == component && CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_PROMPT_DISMISSED == item -> Event.CreditCardAutofillPromptDismissed - Component.FEATURE_CONTEXTMENU to ContextMenuFacts.Items.ITEM -> { + Component.FEATURE_CONTEXTMENU == component && ContextMenuFacts.Items.ITEM == item -> { metadata?.get("item")?.let { Event.ContextMenuItemTapped.create(it.toString()) } } - Component.FEATURE_CONTEXTMENU to ContextMenuFacts.Items.TEXT_SELECTION_OPTION -> { + Component.FEATURE_CONTEXTMENU == component && ContextMenuFacts.Items.TEXT_SELECTION_OPTION == item -> { when (metadata?.get("textSelectionOption")?.toString()) { CONTEXT_MENU_COPY -> Event.ContextMenuCopyTapped CONTEXT_MENU_SEARCH, CONTEXT_MENU_SEARCH_PRIVATELY -> Event.ContextMenuSearchTapped @@ -187,23 +187,23 @@ internal class ReleaseMetricController( } } - Component.BROWSER_TOOLBAR to ToolbarFacts.Items.MENU -> { + Component.BROWSER_TOOLBAR == component && ToolbarFacts.Items.MENU == item -> { metadata?.get("customTab")?.let { Event.CustomTabsMenuOpened } ?: Event.ToolbarMenuShown } - Component.BROWSER_MENU to BrowserMenuFacts.Items.WEB_EXTENSION_MENU_ITEM -> { + Component.BROWSER_MENU == component && BrowserMenuFacts.Items.WEB_EXTENSION_MENU_ITEM == item -> { metadata?.get("id")?.let { Event.AddonsOpenInToolbarMenu(it.toString()) } } - Component.FEATURE_CUSTOMTABS to CustomTabsFacts.Items.CLOSE -> Event.CustomTabsClosed - Component.FEATURE_CUSTOMTABS to CustomTabsFacts.Items.ACTION_BUTTON -> Event.CustomTabsActionTapped + Component.FEATURE_CUSTOMTABS == component && CustomTabsFacts.Items.CLOSE == item -> Event.CustomTabsClosed + Component.FEATURE_CUSTOMTABS == component && CustomTabsFacts.Items.ACTION_BUTTON == item -> Event.CustomTabsActionTapped - Component.FEATURE_MEDIA to MediaFacts.Items.NOTIFICATION -> { + Component.FEATURE_MEDIA == component && MediaFacts.Items.NOTIFICATION == item -> { when (action) { Action.PLAY -> Event.NotificationMediaPlay Action.PAUSE -> Event.NotificationMediaPause else -> null } } - Component.FEATURE_MEDIA to MediaFacts.Items.STATE -> { + Component.FEATURE_MEDIA == component && MediaFacts.Items.STATE == item -> { when (action) { Action.PLAY -> Event.MediaPlayState Action.PAUSE -> Event.MediaPauseState @@ -211,7 +211,7 @@ internal class ReleaseMetricController( else -> null } } - Component.SUPPORT_WEBEXTENSIONS to WebExtensionFacts.Items.WEB_EXTENSIONS_INITIALIZED -> { + Component.SUPPORT_WEBEXTENSIONS == component && WebExtensionFacts.Items.WEB_EXTENSIONS_INITIALIZED == item -> { metadata?.get("installed")?.let { installedAddons -> if (installedAddons is List<*>) { settings.installedAddonsCount = installedAddons.size @@ -228,7 +228,7 @@ internal class ReleaseMetricController( null } - Component.COMPOSE_AWESOMEBAR to ComposeAwesomeBarFacts.Items.PROVIDER_DURATION -> { + Component.BROWSER_AWESOMEBAR == component && ComposeAwesomeBarFacts.Items.PROVIDER_DURATION == item -> { metadata?.get(ComposeAwesomeBarFacts.MetadataKeys.DURATION_PAIR)?.let { providerTiming -> require(providerTiming is Pair<*, *>) { "Expected providerTiming to be a Pair" } when (val provider = providerTiming.first as AwesomeBar.SuggestionProvider) { @@ -247,13 +247,13 @@ internal class ReleaseMetricController( } null } - Component.FEATURE_PWA to ProgressiveWebAppFacts.Items.HOMESCREEN_ICON_TAP -> { + Component.FEATURE_PWA == component && ProgressiveWebAppFacts.Items.HOMESCREEN_ICON_TAP == item -> { Event.ProgressiveWebAppOpenFromHomescreenTap } - Component.FEATURE_PWA to ProgressiveWebAppFacts.Items.INSTALL_SHORTCUT -> { + Component.FEATURE_PWA == component && ProgressiveWebAppFacts.Items.INSTALL_SHORTCUT == item -> { Event.ProgressiveWebAppInstallAsShortcut } - Component.FEATURE_TOP_SITES to TopSitesFacts.Items.COUNT -> { + Component.FEATURE_TOP_SITES == component && TopSitesFacts.Items.COUNT == item -> { value?.let { var count = 0 try { @@ -266,59 +266,59 @@ internal class ReleaseMetricController( } null } - Component.FEATURE_SYNCEDTABS to SyncedTabsFacts.Items.SYNCED_TABS_SUGGESTION_CLICKED -> { + Component.FEATURE_SYNCEDTABS == component && SyncedTabsFacts.Items.SYNCED_TABS_SUGGESTION_CLICKED == item -> { Event.SyncedTabSuggestionClicked } - Component.FEATURE_AWESOMEBAR to AwesomeBarFacts.Items.BOOKMARK_SUGGESTION_CLICKED -> { + Component.FEATURE_AWESOMEBAR == component && AwesomeBarFacts.Items.BOOKMARK_SUGGESTION_CLICKED == item -> { Event.BookmarkSuggestionClicked } - Component.FEATURE_AWESOMEBAR to AwesomeBarFacts.Items.CLIPBOARD_SUGGESTION_CLICKED -> { + Component.FEATURE_AWESOMEBAR == component && AwesomeBarFacts.Items.CLIPBOARD_SUGGESTION_CLICKED == item -> { Event.ClipboardSuggestionClicked } - Component.FEATURE_AWESOMEBAR to AwesomeBarFacts.Items.HISTORY_SUGGESTION_CLICKED -> { + Component.FEATURE_AWESOMEBAR == component && AwesomeBarFacts.Items.HISTORY_SUGGESTION_CLICKED == item -> { Event.HistorySuggestionClicked } - Component.FEATURE_AWESOMEBAR to AwesomeBarFacts.Items.SEARCH_ACTION_CLICKED -> { + Component.FEATURE_AWESOMEBAR == component && AwesomeBarFacts.Items.SEARCH_ACTION_CLICKED == item -> { Event.SearchActionClicked } - Component.FEATURE_AWESOMEBAR to AwesomeBarFacts.Items.SEARCH_SUGGESTION_CLICKED -> { + Component.FEATURE_AWESOMEBAR == component && AwesomeBarFacts.Items.SEARCH_SUGGESTION_CLICKED == item -> { Event.SearchSuggestionClicked } - Component.FEATURE_AWESOMEBAR to AwesomeBarFacts.Items.OPENED_TAB_SUGGESTION_CLICKED -> { + Component.FEATURE_AWESOMEBAR == component && AwesomeBarFacts.Items.OPENED_TAB_SUGGESTION_CLICKED == item -> { Event.OpenedTabSuggestionClicked } - Component.LIB_DATAPROTECT to SecurePrefsReliabilityExperiment.Companion.Actions.EXPERIMENT -> { + Component.LIB_DATAPROTECT == component && SecurePrefsReliabilityExperiment.Companion.Actions.EXPERIMENT == item -> { Event.SecurePrefsExperimentFailure(metadata?.get("javaClass") as String? ?: "null") } - Component.LIB_DATAPROTECT to SecurePrefsReliabilityExperiment.Companion.Actions.GET -> { + Component.LIB_DATAPROTECT == component && SecurePrefsReliabilityExperiment.Companion.Actions.GET == item -> { if (SecurePrefsReliabilityExperiment.Companion.Values.FAIL.v == value?.toInt()) { Event.SecurePrefsGetFailure(metadata?.get("javaClass") as String? ?: "null") } else { Event.SecurePrefsGetSuccess(value ?: "") } } - Component.LIB_DATAPROTECT to SecurePrefsReliabilityExperiment.Companion.Actions.WRITE -> { + Component.LIB_DATAPROTECT == component && SecurePrefsReliabilityExperiment.Companion.Actions.WRITE == item -> { if (SecurePrefsReliabilityExperiment.Companion.Values.FAIL.v == value?.toInt()) { Event.SecurePrefsWriteFailure(metadata?.get("javaClass") as String? ?: "null") } else { Event.SecurePrefsWriteSuccess } } - Component.LIB_DATAPROTECT to SecurePrefsReliabilityExperiment.Companion.Actions.RESET -> { + Component.LIB_DATAPROTECT == component && SecurePrefsReliabilityExperiment.Companion.Actions.RESET == item -> { Event.SecurePrefsReset } - Component.FEATURE_SEARCH to AdsTelemetry.SERP_ADD_CLICKED -> { + Component.FEATURE_SEARCH == component && AdsTelemetry.SERP_ADD_CLICKED == item -> { Event.SearchAdClicked(value!!) } - Component.FEATURE_SEARCH to AdsTelemetry.SERP_SHOWN_WITH_ADDS -> { + Component.FEATURE_SEARCH == component && AdsTelemetry.SERP_SHOWN_WITH_ADDS == item -> { Event.SearchWithAds(value!!) } - Component.FEATURE_SEARCH to InContentTelemetry.IN_CONTENT_SEARCH -> { + Component.FEATURE_SEARCH == component && InContentTelemetry.IN_CONTENT_SEARCH == item -> { Event.SearchInContent(value!!) } - Component.FEATURE_AUTOFILL to AutofillFacts.Items.AUTOFILL_REQUEST -> { + Component.FEATURE_AUTOFILL == component && AutofillFacts.Items.AUTOFILL_REQUEST == item -> { val hasMatchingLogins = metadata?.get(AutofillFacts.Metadata.HAS_MATCHING_LOGINS) as Boolean? if (hasMatchingLogins == true) { Event.AndroidAutofillRequestWithLogins @@ -326,21 +326,21 @@ internal class ReleaseMetricController( Event.AndroidAutofillRequestWithoutLogins } } - Component.FEATURE_AUTOFILL to AutofillFacts.Items.AUTOFILL_SEARCH -> { + Component.FEATURE_AUTOFILL == component && AutofillFacts.Items.AUTOFILL_SEARCH == item -> { if (action == Action.SELECT) { Event.AndroidAutofillSearchItemSelected } else { Event.AndroidAutofillSearchDisplayed } } - Component.FEATURE_AUTOFILL to AutofillFacts.Items.AUTOFILL_LOCK -> { + Component.FEATURE_AUTOFILL == component && AutofillFacts.Items.AUTOFILL_LOCK == item -> { if (action == Action.CONFIRM) { Event.AndroidAutofillUnlockSuccessful } else { Event.AndroidAutofillUnlockCanceled } } - Component.FEATURE_AUTOFILL to AutofillFacts.Items.AUTOFILL_CONFIRMATION -> { + Component.FEATURE_AUTOFILL == component && AutofillFacts.Items.AUTOFILL_CONFIRMATION == item -> { if (action == Action.CONFIRM) { Event.AndroidAutofillConfirmationSuccessful } else {