For #15279: add LazyMonitored and tests.
parent
de3c4bc635
commit
f37ace0630
@ -0,0 +1,44 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.perf
|
||||
|
||||
import mozilla.components.support.base.log.logger.Logger
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
private val logger = Logger("LazyMonitored")
|
||||
|
||||
/**
|
||||
* A container for the number of components initialized.
|
||||
*/
|
||||
object ComponentInitCount {
|
||||
val count = AtomicInteger(0)
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for setting the [LazyMonitored] property delegate, which wraps
|
||||
* [lazy] to add performance monitoring.
|
||||
*/
|
||||
fun <T> lazyMonitored(initializer: () -> T) = LazyMonitored(initializer)
|
||||
|
||||
/**
|
||||
* A wrapper around the [lazy] property delegate to monitor for performance related issues.
|
||||
* For example, we can count the number of components initialized to see how the number of
|
||||
* components initialized on start up impacts start up time.
|
||||
*/
|
||||
class LazyMonitored<T>(initializer: () -> T) {
|
||||
// Lazy is thread safe.
|
||||
private val lazyValue = lazy {
|
||||
// We're unlikely to have 4 billion components so we don't handle overflow.
|
||||
val componentInitCount = ComponentInitCount.count.incrementAndGet()
|
||||
|
||||
initializer().also {
|
||||
@Suppress("UNNECESSARY_NOT_NULL_ASSERTION") // the compiler fails with !! but warns with !!.
|
||||
val className = if (it == null) "null" else it!!::class.java.canonicalName
|
||||
logger.debug("Init component #$componentInitCount: $className")
|
||||
}
|
||||
}
|
||||
|
||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): T = lazyValue.value
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.perf
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
class LazyMonitoredTest {
|
||||
|
||||
private val componentInitCount get() = ComponentInitCount.count.get()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
ComponentInitCount.count.set(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN using the convenience function THEN it returns a lazy monitored`() {
|
||||
val actual = lazyMonitored { }
|
||||
assertEquals(LazyMonitored::class, actual::class)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN accessing a lazy monitored THEN it returns the initializer value`() {
|
||||
val actual by lazyMonitored { 4 }
|
||||
assertEquals(4, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN accessing a lazy monitored THEN the component init count is incremented`() {
|
||||
assertEquals(0, componentInitCount)
|
||||
|
||||
val monitored by lazyMonitored { }
|
||||
// We must access the value to trigger init.
|
||||
@Suppress("UNUSED_EXPRESSION") monitored
|
||||
|
||||
assertEquals(1, componentInitCount)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue