Minimalny czas wykonania funkcji

0

Witam,

Mam taki oto przykładowy kod:

setInterval(function(){
	funkcja();
},100);

Kod w funkcja() jest dość obszerny i ma kilka odwołań do dom, w zależności od ustawień w pewnym momencie, wykonuje się w czasie od 1ms do około 10ms. W efekcie od jednej iteracji setInterval do następnej zwykle upływa od 101ms do 110ms (jeśli dobrze rozumiem, że czas kodu nie wlicza się do czasu setTimeout()/setInterval()). Powiedzmy, że teraz muszę to z czymś zsynchronizować i po pewnym czasie te rozbieżności kilku ms robią różnicę. Chciałbym by czas wykonania funkcja() niezależnie od tego czy się tam będzie działo dużo czy mało wynosił 15ms. Macie może jakieś sugestie jak podejść do tego problemu. Myślałem żeby zrobić na początku i na końcu setInterval jakiś performance.now() i potem jakiś if, jak czas mniejszy od 15ms to puszczam jakąś funkcje zabierającą czas (petla z jakimiś obliczeniami) i znów sprawdzanie.

0

Korzystaj z setTimeout(). Interval zbiera tylko do kolejki (która może się zapchać), a Timeout pozwala uzyskać stosunkowo równe odstępy - nie zwracając uwagi na czas wykonania kodu.

0
Zielony Banan napisał(a):

Korzystaj z setTimeout(). Interval zbiera tylko do kolejki (która może się zapchać), a Timeout pozwala uzyskać stosunkowo równe odstępy - nie zwracając uwagi na czas wykonania kodu.

Niby tak, ale Interval() mam w dość dużych odstępach, a kod wykonuje się dużo szybciej, może przerobie jeszcze na Timeout(). Przydałby mi się jeszcze jakiś typowy sleep() :) .

1

Nie osiągniesz tego w javascriptcie (prawie na pewno). To nie Java tutaj nie ma wielowątkowości. W js jest coś takiego jak event loop. Ani setTimeout, ani setInterval nie gwarantuje odstępu. Jedyne co robi to gwarantuje Ci, że dane wydarzenie nie nastąpi wcześniej, ale może i prawie na pewno wystąpi później niż się tego spodziewasz.

Polecam genialny talk na temat event loop

0
Skayfer napisał(a):

jeśli dobrze rozumiem, że czas kodu nie wlicza się do czasu setTimeout()/setInterval()

To źle rozumiesz.
Ani setInterval, ani setTimeout nie gwarantuje interwału/opóźnienia, możesz być tylko pewien, że częstotliwość nie będzie większa. 100ms w praktyce może oznaczać i 100.1ms i 200ms. Nie da się w js zagwarantować wywoływania kodu w równych odstępach czasu. Na systemie łagodnego czasu rzeczywistego w ogóle nie da się tego zagwarantować niezależnie od języka programowania (być może da się na poziomie sterownika).

1

Nie wiem co piszesz, ale miej też na uwadze, że przeglądarki mają dynamicznie określany minimalny czas. Np. O ILE DOBRZE PAMIĘTAM Internet Explorer i chyba Chrome (musisz szukać) na zasilaniu z baterii zignoruje wartości poniżej 50ms i choćbyś napisał 1, czy 30 - wykona się za minimum 50ms. W przypadku IE wartość ta (również o ile dobrze pamiętam) może być dodatkowo tuningowana przez użytkownika/system, tj. w trybie oszczędzania baterii wartość ta będzie dużo większa.

Dodatkowo w Chrome i zapewne innych przeglądarkach (jw.) - wartość ta rośnie wraz z czasem kiedy karta/okno przeglądarki pozostają nieaktywne. Tj. z początku będzie to powiedzmy 10ms, potem zwiększy się do 50, 100, a ostatecznie nawet kilku sekund.

Największą dokładność uzyskasz przez requestAnimationFrame i porównywanie czasu, ale RAF w ogóle się nie wykona jeżeli karta jest nieaktywna, a także może obciążać CPU.

Jeżeli dokładniej opiszesz co próbujesz zrobić to możemy pomyśleć nad najsensowniejszą/alternatywną opcją.

1 użytkowników online, w tym zalogowanych: 0, gości: 1