all: do not do work on static initialization

Try to lazily initialize certain static variables that do work (like
Regex) to speed up initialization time.
This commit is contained in:
Alexander Capehart 2023-05-11 13:04:07 -06:00
parent c98ca8712f
commit a5176d6209
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
9 changed files with 30 additions and 34 deletions

View file

@ -568,8 +568,8 @@ private inline fun <T : Music, K> compareByDynamic(
} }
/** /**
* Utility function to create a [Comparator] that sorts in ascending order based on the * Utility function to create a [Comparator] that sorts in ascending order based on the given
* given [Comparator], with a selector based on the item itself. * [Comparator], with a selector based on the item itself.
* *
* @param comparator The [Comparator] to wrap. * @param comparator The [Comparator] to wrap.
* @return A new [Comparator] with the specified configuration. * @return A new [Comparator] with the specified configuration.
@ -581,8 +581,8 @@ private fun <T : Music> compareBy(comparator: Comparator<T>): Comparator<T> =
/** /**
* A [Comparator] that chains several other [Comparator]s together to form one comparison. * A [Comparator] that chains several other [Comparator]s together to form one comparison.
* *
* @param comparators The [Comparator]s to chain. These will be iterated through in order * @param comparators The [Comparator]s to chain. These will be iterated through in order during a
* during a comparison, with the first non-equal result becoming the result. * comparison, with the first non-equal result becoming the result.
*/ */
private class MultiComparator<T>(vararg comparators: Comparator<T>) : Comparator<T> { private class MultiComparator<T>(vararg comparators: Comparator<T>) : Comparator<T> {
private val _comparators = comparators private val _comparators = comparators
@ -656,8 +656,8 @@ private class BasicComparator<T : Music> private constructor() : Comparator<T> {
} }
/** /**
* A [Comparator] that compares two possibly null values. Values will be considered lesser * A [Comparator] that compares two possibly null values. Values will be considered lesser if they
* if they are null, and greater if they are non-null. * are null, and greater if they are non-null.
*/ */
private class NullableComparator<T : Comparable<T>> private constructor() : Comparator<T?> { private class NullableComparator<T : Comparable<T>> private constructor() : Comparator<T?> {
override fun compare(a: T?, b: T?) = override fun compare(a: T?, b: T?) =

View file

@ -23,6 +23,8 @@ import android.content.pm.PackageManager
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
@ -32,12 +34,9 @@ import org.oxycblt.auxio.music.device.RawSong
import org.oxycblt.auxio.music.fs.MediaStoreExtractor import org.oxycblt.auxio.music.fs.MediaStoreExtractor
import org.oxycblt.auxio.music.metadata.TagExtractor import org.oxycblt.auxio.music.metadata.TagExtractor
import org.oxycblt.auxio.music.user.UserLibrary import org.oxycblt.auxio.music.user.UserLibrary
import org.oxycblt.auxio.util.fallible
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.logE import org.oxycblt.auxio.util.logE
import org.oxycblt.auxio.util.logW import org.oxycblt.auxio.util.logW
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
/** /**
* Primary manager of music information and loading. * Primary manager of music information and loading.
@ -293,7 +292,7 @@ constructor(
val incompleteSongs = Channel<RawSong>(Channel.UNLIMITED) val incompleteSongs = Channel<RawSong>(Channel.UNLIMITED)
val mediaStoreJob = val mediaStoreJob =
worker.scope.tryAsync { worker.scope.tryAsync {
mediaStoreExtractor.consume(query, cache, incompleteSongs, completeSongs) }.also { mediaStoreExtractor.consume(query, cache, incompleteSongs, completeSongs)
incompleteSongs.close() incompleteSongs.close()
} }
val metadataJob = val metadataJob =
@ -326,7 +325,10 @@ constructor(
worker.scope.tryAsync(Dispatchers.Main) { worker.scope.tryAsync(Dispatchers.Main) {
deviceLibraryFactory.create(rawSongs).also { deviceLibraryChannel.send(it) } deviceLibraryFactory.create(rawSongs).also { deviceLibraryChannel.send(it) }
} }
val userLibraryJob = worker.scope.tryAsync { userLibraryFactory.read(deviceLibraryChannel) } val userLibraryJob =
worker.scope.tryAsync {
userLibraryFactory.read(deviceLibraryChannel).also { deviceLibraryChannel.close() }
}
if (cache == null || cache.invalidated) { if (cache == null || cache.invalidated) {
cacheRepository.writeCache(rawSongs) cacheRepository.writeCache(rawSongs)
} }

View file

@ -185,9 +185,10 @@ class Date private constructor(private val tokens: List<Int>) : Comparable<Date>
* A [Regex] that can parse a variable-precision ISO-8601 timestamp. Derived from * A [Regex] that can parse a variable-precision ISO-8601 timestamp. Derived from
* https://github.com/quodlibet/mutagen * https://github.com/quodlibet/mutagen
*/ */
private val ISO8601_REGEX = private val ISO8601_REGEX by lazy {
Regex( Regex(
"""^(\d{4})([-.](\d{2})([-.](\d{2})([T ](\d{2})([:.](\d{2})([:.](\d{2})(Z)?)?)?)?)?)?$""") """^(\d{4})([-.](\d{2})([-.](\d{2})([T ](\d{2})([:.](\d{2})([:.](\d{2})(Z)?)?)?)?)?)?$""")
}
/** /**
* Create a [Date] from a year component. * Create a [Date] from a year component.

View file

@ -35,7 +35,7 @@ sealed interface Name : Comparable<Name> {
/** /**
* A logical first character that can be used to collate a sorted list of music. * A logical first character that can be used to collate a sorted list of music.
* *
* TODO: Move this to the home view * TODO: Move this to the home package
*/ */
val thumb: String val thumb: String
@ -87,7 +87,7 @@ sealed interface Name : Comparable<Name> {
final override val thumb: String final override val thumb: String
get() = get() =
// TODO: Remove these checks once you have real unit testing // TODO: Remove these safety checks once you have real unit testing
sortTokens sortTokens
.firstOrNull() .firstOrNull()
?.run { collationKey.sourceString.firstOrNull() } ?.run { collationKey.sourceString.firstOrNull() }
@ -114,8 +114,7 @@ sealed interface Name : Comparable<Name> {
* *
* @param raw The raw name obtained from the music item * @param raw The raw name obtained from the music item
* @param sort The raw sort name obtained from the music item * @param sort The raw sort name obtained from the music item
* @param musicSettings [MusicSettings] required to obtain user-preferred sorting * @param musicSettings [MusicSettings] required for name configuration.
* configurations
*/ */
fun from(raw: String, sort: String?, musicSettings: MusicSettings): Known = fun from(raw: String, sort: String?, musicSettings: MusicSettings): Known =
if (musicSettings.intelligentSorting) { if (musicSettings.intelligentSorting) {
@ -145,7 +144,7 @@ sealed interface Name : Comparable<Name> {
} }
private val COLLATOR: Collator = Collator.getInstance().apply { strength = Collator.PRIMARY } private val COLLATOR: Collator = Collator.getInstance().apply { strength = Collator.PRIMARY }
private val PUNCT_REGEX = Regex("[\\p{Punct}+]") private val PUNCT_REGEX by lazy { Regex("[\\p{Punct}+]") }
/** /**
* Plain [Name.Known] implementation that is internationalization-safe. * Plain [Name.Known] implementation that is internationalization-safe.
@ -215,6 +214,6 @@ private data class IntelligentKnownName(override val raw: String, override val s
} }
companion object { companion object {
private val TOKEN_REGEX = Regex("(\\d+)|(\\D+)") private val TOKEN_REGEX by lazy { Regex("(\\d+)|(\\D+)") }
} }
} }

View file

@ -209,7 +209,7 @@ private fun String.parseId3v1Genre(): String? {
* A [Regex] that implements parsing for ID3v2's genre format. Derived from mutagen: * A [Regex] that implements parsing for ID3v2's genre format. Derived from mutagen:
* https://github.com/quodlibet/mutagen * https://github.com/quodlibet/mutagen
*/ */
private val ID3V2_GENRE_RE = Regex("((?:\\((\\d+|RX|CR)\\))*)(.+)?") private val ID3V2_GENRE_RE by lazy { Regex("((?:\\((\\d+|RX|CR)\\))*)(.+)?") }
/** /**
* Parse an ID3v2 integer genre field, which has support for multiple genre values and combined * Parse an ID3v2 integer genre field, which has support for multiple genre values and combined

View file

@ -47,6 +47,11 @@ private constructor(
*/ */
inline fun edit(edits: MutableList<Song>.() -> Unit) = edit(songs.toMutableList().apply(edits)) inline fun edit(edits: MutableList<Song>.() -> Unit) = edit(songs.toMutableList().apply(edits))
override fun equals(other: Any?) =
other is PlaylistImpl && uid == other.uid && songs == other.songs
override fun hashCode() = 31 * uid.hashCode() + songs.hashCode()
companion object { companion object {
/** /**
* Create a new instance with a novel UID. * Create a new instance with a novel UID.

View file

@ -294,6 +294,6 @@ constructor(
* Matches non-float information from ReplayGain adjustments. Derived from vanilla music: * Matches non-float information from ReplayGain adjustments. Derived from vanilla music:
* https://github.com/vanilla-music/vanilla * https://github.com/vanilla-music/vanilla
*/ */
val REPLAYGAIN_ADJUSTMENT_FILTER_REGEX = Regex("[^\\d.-]") val REPLAYGAIN_ADJUSTMENT_FILTER_REGEX by lazy { Regex("[^\\d.-]") }
} }
} }

View file

@ -125,7 +125,8 @@ class SearchEngineImpl @Inject constructor(@ApplicationContext private val conte
* Converts the output of [Normalizer] to remove any junk characters added by it's * Converts the output of [Normalizer] to remove any junk characters added by it's
* replacements, alongside punctuation. * replacements, alongside punctuation.
*/ */
val NORMALIZE_POST_PROCESSING_REGEX = val NORMALIZE_POST_PROCESSING_REGEX by lazy {
Regex("(\\p{InCombiningDiacriticalMarks}+)|(\\p{Punct})") Regex("(\\p{InCombiningDiacriticalMarks}+)|(\\p{Punct})")
}
} }
} }

View file

@ -34,18 +34,6 @@ fun <T> unlikelyToBeNull(value: T?) =
value!! value!!
} }
/**
* Maps a try expression to a [Result].
* @param block The code to execute
* @return A [Result] representing the outcome of [block]'s execution.
*/
inline fun <reified R> fallible(block: () -> R) =
try {
Result.success(block())
} catch (e: Exception) {
Result.failure(e)
}
/** /**
* Aliases a check to ensure that the given number is non-zero. * Aliases a check to ensure that the given number is non-zero.
* *