несогласованная скорость выполнения 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 ответ

Код, который вы запускаете в режиме отладки, всегда будет медленнее, чем скомпилированное приложение. Это не тот же код — это приближение, но с добавленными слоями для простоты использования и отладки. Скорее всего, ваш веб-браузер работает на гораздо более мощном процессоре, что может объяснить прирост производительности.

Что касается скомпилированного приложения, работающего с опережением графика, это более интересно, и у меня нет на этот счет хорошей теории. Возможно, собственная среда пытается компенсировать обработку, которую она выполняет в другом месте, и запускает ваш таймер слишком рано. Если вы позволите ему поработать какое-то время, будет ли он быстрее по сравнению с часами?

Другие вопросы по тегам