Pchełki PowerShell: co trwa dłużej, średnik czy przecinek?

https://xpil.eu/dyp

Udowodnimy dziś, że średnik zajmuje więcej czasu od przecinka.

(Proszę nie regulować odbiorników, naprawdę będziemy dziś mierzyć czas trwania przecinka i porównywać go z czasem trwania średnika)

Ponieważ w świecie komputerów rzeczy wydarzają się naprawdę szybko, oczywiście pod warunkiem, że się nam za bardzo nie spieszy, skonstruujemy sobie dziś całkiem dokładny stoper, który potrafi mierzyć czas z dokładnością do jednej dziesięciomilionowej części sekundy.

Jak to możliwe?

Całkiem prosto. Procesory pracują z częstotliwościami mierzonymi w gigahercach, czyli miliardach tyknięć na sekundę. Żeby odmierzyć jedną dziesięciomilionową sekundy, jednogigahercowy CPU ma aż sto tyknięć do dyspozycji, a więc całkiem sporo.

Tu mała dygresja: taka rozdzielczość rzadko przydaje się do praktycznego odmierzania czasu - nikogo tak naprawdę nie interesuje, czy sportowiec przekroczył linię mety teraz czy jedną mikrosekundę później. Jednak jeżeli chcemy ustalić *kolejność* wydarzeń w naszej aplikacji - o, tu już tak wysoka rozdzielczość może się przydać. I tu pojawia się ciekawostka: jeżeli czasy wystąpienia dwóch zarejestrowanych uprzednio wydarzeń różnią się między sobą o mniej niż dwie dziesięciomilionowe sekundy, wówczas faktyczna kolejność ich wystąpienia nie może być ustalona ponad wszelką wątpliwość, jeżeli aplikacja jest uruchomiona na procesorze wielowątkowym. W scenariuszu z jednym wątkiem ten problem nie występuje.

Wróćmy jednak do mierzenia znaków interpunkcyjnych. Co trwa dłużej: średnik czy przecinek?

Najpierw obiecany wcześniej stoper:

$stoper = New-Object System.Diagnostics.Stopwatch
$stoper.Start()

Teraz sprawdźmy, czy stoper faktycznie działa:

$stoper.Elapsed.TotalMilliseconds

Wynik:

31495.6849

A więc od wystartowania stopera upłynęło trzydzieści jeden sekund, czterysta dziewięćdziesiąt pięć milisekund i sześćset osiemdziesiąt cztery koma dziewięć mikrosekund.

W jaki sposób możemy teraz wykorzystać tą maszynerię do pomiaru czasu trwania średnika? Przecinka?

Szczęśliwie się złożyło, że obydwa te znaki są częścią standardowej składni PowerShell, a więc:

$stoper.Elapsed.TotalMilliseconds;$stoper.Elapsed.TotalMilliseconds

Wynik:

154988.0604
154988.6597

Wychodzi na to, że średnik trwa nieco ponad pół milisekundy.

Powtórzmy pomiar dla pewności:

$stoper.Elapsed.TotalMilliseconds;$stoper.Elapsed.TotalMilliseconds
248693.5893
248693.9295
$stoper.Elapsed.TotalMilliseconds;$stoper.Elapsed.TotalMilliseconds
249084.3434
249084.6673
$stoper.Elapsed.TotalMilliseconds;$stoper.Elapsed.TotalMilliseconds
249500.4768
249500.7762
$stoper.Elapsed.TotalMilliseconds;$stoper.Elapsed.TotalMilliseconds
249836.617
249837.0411
$stoper.Elapsed.TotalMilliseconds;$stoper.Elapsed.TotalMilliseconds
250140.6742
250141.1017
$stoper.Elapsed.TotalMilliseconds;$stoper.Elapsed.TotalMilliseconds
250404.6521
250405.0077

Jak widać kolejne pomiary pokazują czasy trwania średnika w okolicach pół milisekundy, może odrobinę mniej.

Sprawdźmy teraz jak sprawa wygląda z przecinkiem:

$stoper.Elapsed.TotalMilliseconds,$stoper.Elapsed.TotalMilliseconds
391970.0603
391970.0666
$stoper.Elapsed.TotalMilliseconds,$stoper.Elapsed.TotalMilliseconds
394493.7502
394493.7571
$stoper.Elapsed.TotalMilliseconds,$stoper.Elapsed.TotalMilliseconds
394981.6155
394981.6222
$stoper.Elapsed.TotalMilliseconds,$stoper.Elapsed.TotalMilliseconds
395366.0361
395366.0421
$stoper.Elapsed.TotalMilliseconds,$stoper.Elapsed.TotalMilliseconds
395701.8795
395701.8859
$stoper.Elapsed.TotalMilliseconds,$stoper.Elapsed.TotalMilliseconds
395965.5808
395965.5866
$stoper.Elapsed.TotalMilliseconds,$stoper.Elapsed.TotalMilliseconds
396252.0871
396252.0914
$stoper.Elapsed.TotalMilliseconds,$stoper.Elapsed.TotalMilliseconds
396477.6277
396477.6343

Oho, przecinek jest o wiele szybszy! Wygląda na to, że trwa niecałe dziesięć mikrosekund, czyli prawie dwa rzędy wielkości krócej!

Wynika to z tego, że przecinek jest mniejszy i bardziej zwinny, a więc w efekcie zużywa mnie pamięci i jest dużo szybszy.

Wniosek: chcesz zaoszczędzić na czasie, używaj przecinków zamiast średników. Prawdziwi programiści czniają średniki!

A teraz na serio:

Konstrukcja typu $a,$b zwraca tablicę dwuelementową, która następnie jest wyświetlana na konsoli. Czyli tak: najpierw wykona się $a, potem $b, potem wyniki zostaną wrzucone do tablicy i dopiero na koniec treść tablicy zostaje wypisana na ekran. Nawet jeżeli wypisanie na ekran trwa długo, to wykonuje się ono już po wykonaniu $b, a więc nie ma żadnego wpływu na "czas trwania" przecinka.

Natomiast konstrukcja typu $a;$b wykonuje $a, wyświetla wynik, następnie wykonuje $b i znów wyświetla wynik. Mamy więc dwie operacje wejścia - wyjścia, z których pierwsza ma wpływ na "czas trwania" średnika. Ponieważ konsola jest bardzo, ale to bardzo powolna w porównaniu do operacji w pamięci, ten wariant pokaże o wiele dłuższy czas. W moim przypadku prawie dwa rzędy wielkości różnicy

https://xpil.eu/dyp

4 komentarze

  1. Ziom. Średnik to przecinek z kropką, a przecinek jest sam. Rysowanie średnika zaczyna lub kończy się kropką, a przecinek po przerwie.
    Ale wywód ładny, ładna prezentacja… ziom, masz za dużo czasu w pracy 😀

    1. Napisze z 5-10 skryptów, które odwalają za niego 90% roboty, a jego jedyną czynnością jest uruchomienie ich rano… pewnie, że ma potem dużo czasu. Stąd my możemy cieszyć się wpisami na blogu.
      profit!

      1. A wiesz, że jedną z najczęściej spotykanych porad odnośnie optymalizacji czasu pracy jest: “zautomatyzuj sobie to”?

        Dowcip (ponury) polega jednak na tym, że jako osobnik raczej uczciwy nie pozwalam sobie na zbyt rozrzutne szastanie wolnym czasem w pracy i jak już sobie coś zautomatyzuję to zaraz potem szukam kolejnego zajęcia. W ten sposób początkowe 90% kurczy się do 20%, przynajmniej dopóki nie zautomatyzuję tego nowego kawałka 🙂 I tak się to kręci…

  2. A jak długo trwa brak średnika albo przecinka!!! Zmieniam kod SQL, uruchamiam i trach! Komunikat błędu. Siedzę potem i szukam, gdzie i dlaczego “; expected”…

Leave a Comment

Komentarze mile widziane.

Jeżeli chcesz do komentarza wstawić kod, użyj składni:
[code]
tutaj wstaw swój kod
[/code]

Jeżeli zrobisz literówkę lub zmienisz zdanie, możesz edytować komentarz po jego zatwierdzeniu.