Funkcje czasowe w R [zamknięte]

36
  1. Chciałbym zmierzyć czas potrzebny do powtórzenia działania funkcji. Czy replicate()używanie pętli for jest równoważne? Na przykład:

    system.time(replicate(1000, f()));
    system.time(for(i in 1:1000){f()});

    Która jest preferowaną metodą.

  2. Na wyjściu system.time(), to sys+userrzeczywisty czas CPU na uruchomienie programu? Czy elapseddobra miara wydajności programu w czasie?

Tim
źródło
3
Dla przypomnienia, ponieważ wyraźnie spóźniłem się, aby zmienić bieg tego pytania: jest to rodzaj problemu, który moim zdaniem najlepiej nadaje się do StackOverflow.
Matt Parker,
2
@Matt Zgadzam się, że pytania dotyczące tego, jak raz program jest odpowiedni dla SO. Zgadzam się również, że dosłowna interpretacja tego pytania (przyjęta w kilku odpowiedziach) umieściłaby je tutaj w CV. Wydaje się jednak, że istnieje pewne zainteresowanie statystyczne w projektowaniu eksperymentu czasowego i analizie wyników takiego eksperymentu.
whuber

Odpowiedzi:

19

Aby efektywnie mierzyć czas programów, szczególnie gdy chcesz porównać alternatywne rozwiązania, potrzebujesz kontroli! Dobrym sposobem jest umieszczenie procedury, którą mierzysz w funkcji. Wywołaj funkcję w pętli czasowej. Napisz procedurę skrótową, w zasadzie usuwając cały kod z funkcji i po prostu wracając z niego (ale zostaw wszystkie argumenty w środku). Umieść kod pośredniczący w pętli pomiaru czasu i ponownie ustaw czas. Mierzy to cały narzut związany z taktowaniem. Odejmij czas pośredni od czasu procedury, aby uzyskać sieć: powinien to być dokładny pomiar rzeczywistego potrzebnego czasu.

N.mN./m

Korzystając z tych podstawowych zasad projektowania eksperymentalnego, zasadniczo kontrolujesz wszelkie różnice wynikające z tego, jak wdrażasz kod (np. Różnica między pętlą for a replicate ()). To sprawia, że ​​twój problem zniknął.

Whuber
źródło
25

Jeśli chodzi o twoje dwa punkty:

  1. To stylistyka. Podoba mi się, replicate()ponieważ jest funkcjonalny.
  2. Zazwyczaj koncentruję się na elapsed, tj. Na trzeciej liczbie.

Często to robię

N <- someNumber
mean(replicate( N, system.time( f(...) )[3], trimmed=0.05) )

aby uzyskać skróconą średnią wynoszącą 90% N powtórzeń połączeń f().

(Edytowane, dzięki dzięki Hadley za złapanie cienkiego).

Dirk Eddelbuettel
źródło
2
Nie masz na myśli mean(replicate(N, system.time(f(...))[3]), trim = 0.05)?
hadley,
2
Jeśli wywołanie f () jest długie, jest w porządku. Jeśli jednak wywołanie f () jest krótkie, wówczas narzut wywołania synchronizacji prawdopodobnie zwiększy pomiar błędu. Z jednym wywołaniem funkcji system.time () w wielu powtórzeniach f () można podzielić błąd wywołania, dopóki nie będzie to jakaś nieskończenie mała wartość (i wraca szybciej).
Jan
@John: Dzięki, ale nie rozumiem tego, co powiedziałeś. Nadal zastanawiam się, co jest lepsze, powtarzając f () wewnątrz lub na zewnątrz system.time ()?
Tim
Każde wywołanie komendy system.time () ma pewien zmienny czas potrzebny na wywołanie, który powoduje pewną ilość błędu pomiaru. To niewielka ilość. Ale co jeśli f () jest bardzo krótkim wywołaniem? Następnie błąd ten można połączyć z czasem potrzebnym na wywołanie f (). Tak więc, gdy wywołujesz f () 1e5 razy w jednym wywołaniu system.time (), błąd dzieli się na 1e5 części. Gdy wywołujesz system.time () dla każdego f (), jego wpływ może być znaczący, jeśli czas dla f () jest krótki. Oczywiście, jeśli potrzebujesz jedynie względnego czasu, nie ma to większego znaczenia.
Jan
Aha, a druga część jest taka, że ​​szybciej byłoby po prostu wywołać system.call () raz.
Jan
10

Możesz także skorzystać z czasu zwróconego przez Sys.time; to oczywiście mierzy czas ściany, a więc czas obliczeń w czasie rzeczywistym. Przykładowy kod:

Sys.time()->start;
replicate(N,doMeasuredComputation());
print(Sys.time()-start);

źródło
3

Jeśli chodzi o to, którego pomiaru czasu użyć, nie mogę dodać innych respondentów.

Jeśli chodzi o używaną funkcję, lubię używać testu porównawczego? Z pakietu rbenchmark .

Tal Galili
źródło
1

Robią różne rzeczy. Czas, co chcesz zrobić. replicate () zwraca wektor wyników każdego wykonania funkcji. Pętla for nie. Dlatego nie są równoważnymi stwierdzeniami.

Ponadto określ czas, w jaki sposób chcesz coś zrobić. Następnie możesz znaleźć najbardziej wydajną metodę.

Jan
źródło
mod-tip: opublikuj drugą część jako komentarz do odpowiedzi Dirka.