несогласованная скорость выполнения setinterval в expo-проекте на разных платформах (web, expo go и apk)
Я запускаю функцию каждую секунду и наблюдаю, сколько времени она выполняется, сравнивая с ее точным временем выполнения.
Когда я запускаю приведенный ниже код, используя открытую сеть expo, скорость рендеринга / выполнения компонента в порядке, и я вижу, что время Date.now идет взад-вперед с приблизительным отклонением в 10 миллисекунд, что отлично.
Однако, когда я запускаю этот код на своем телефоне с помощью expo go. Скорость выполнения замедляется из-за кучи, а снос постепенно увеличивается. Я предполагаю, что это вызвано тем, что выставка имитирует окружающую среду.
Обновление: Но тогда все становится действительно интересным: после компиляции apk (expo build:android -t apk) время выполнения каждого счета на самом деле постоянно меньше 1 секунды. Поскольку в 5-й раз время выполнения от Date может быть 1637372693 123, время выполнения в 6-й раз будет 1637372694 110.
Это наблюдается более чем в 400 случаях выполнения и потенциально может быть более серьезной проблемой. Я хотел бы знать систематический способ решения этой проблемы.
import React, { useEffect, useState } from "react";
import {Text,Button, View} from 'react-native';
export default function Home(props){
const [timerCount, setTimer] = useState(parseInt(props.time))
const [timepair,setTimePair] = useState([[0,0]])
const [start,setStart] = useState(false)
useEffect(() => {
let interval = setInterval(() => {
setTimer(lastTimerCount => {
//lastTimerCount <= 0 && clearInterval(interval);
//console.log(lastTimerCount)
if (lastTimerCount === 0){
return props.time
} else{
return lastTimerCount - 1
}
});
setTimePair(lasttimepair=>{
let timepair = JSON.parse(JSON.stringify(lasttimepair))
timepair.push([timepair[timepair.length-1][0]+1,(new Date()).getTime()])
return timepair
});
}, 1000) //each count lasts for a second
//cleanup the interval on complete
return () => clearInterval(interval)
}, []);
return (
<View>
<Text>{timerCount}</Text>
<Text>{timepair[timepair.length-1]} </Text>
<Button title = "start" onPress = {()=>setStart(startstatus=>{return !startstatus})}/>
<Text>{String(start)}</Text>
</View>
)
}
1 ответ
Код, который вы запускаете в режиме отладки, всегда будет медленнее, чем скомпилированное приложение. Это не тот же код — это приближение, но с добавленными слоями для простоты использования и отладки. Скорее всего, ваш веб-браузер работает на гораздо более мощном процессоре, что может объяснить прирост производительности.
Что касается скомпилированного приложения, работающего с опережением графика, это более интересно, и у меня нет на этот счет хорошей теории. Возможно, собственная среда пытается компенсировать обработку, которую она выполняет в другом месте, и запускает ваш таймер слишком рано. Если вы позволите ему поработать какое-то время, будет ли он быстрее по сравнению с часами?