Na crowdsourcingové platformě Crowd Supply byla spuštěna kampaň na podporu open source biometrického monitoru ve tvaru hodinek HealthyPi Move. Cena je 249 dolarů a plánovaný termín dodání listopad letošního roku.
Firma Murena představila /e/OS verze 2.0. Jde o alternativní sestavení Androidu bez aplikací Google. Mezi novinkami je podrobnější nastavení ochrany soukromí před sledováním aplikacemi. Murena prodává několik smartphonů s předinstalovaným /e/OS (Fairphone, repasovaný Google Pixel 5).
Do 30. května lze v rámci akce Warhammer Skulls 2024 získat na Steamu zdarma hru Warhammer 40,000: Gladius - Relics of War.
HelenOS (Wikipedie), tj. svobodný operační systém českého původu založený na architektuře mikrojádra, byl vydán ve verzi 0.14.1. Přehled novinek v poznámkách k vydání. Vypíchnou lze nabídku Start. Videopředstavení na YouTube.
BreadboardOS je firmware pro Raspberry Pi Pico (RP2040) umožňující s tímto MCU komunikovat pomocí řádkového rozhraní (CLI). Využívá FreeRTOS a Microshell.
Vývojáři KDE oznámili vydání balíku aplikací KDE Gear 24.05. Přehled novinek i s náhledy a videi v oficiálním oznámení. Do balíku se dostalo 5 nových aplikací: Audex, Accessibility Inspector, Francis, Kalm a Skladnik.
Byla vydána (𝕏) nová verze 18.0.0 open source webového aplikačního frameworku Angular (Wikipedie). Přehled novinek v příspěvku na blogu.
V neděli 26. května lze navštívit Maker Faire Rychnov nad Kněžnou, festival plný workshopů, interaktivních činností a především nadšených a zvídavých lidí.
Byla vydána nová stabilní verze 3.20.0, tj. první z nové řady 3.20, minimalistické linuxové distribuce zaměřené na bezpečnost Alpine Linux (Wikipedie) postavené na standardní knihovně jazyka C musl libc a BusyBoxu. Z novinek lze vypíchnou počáteční podporu 64bitové architektury RISC-V.
Tak jsem uvnitř podmínky grep
u potřeboval vyhodnotit nějakou složitější věc a měl jsem možnost napsat to jako annonymní sub
a nebo do
. Položil jsem si otázku co bude rychlejší?
Vnitřek podmínky grep
u vypadal nějak podobně takhle:
my $attr = $_; my $successors = $successors{$attr}; $successors and do { my $res; $res = exists $successors->{$_} and last foreach (predecessors($attr)); !$res }
my $attr = $_; my $successors = $successors{$attr}; $successors and sub { exists $successors->{$_} && return 0 foreach predecessors($attr); 1 }->()
Výsledný kód jsem trošku benchmarkoval a verze se sub
je až o 50% pomalejší (samozřejmě v závislosti na okolní režiji). Ale proč? Odpověď je celkem jednoduchá, annonymní subrutina se pokaždé znovu skompiluje. (Trošku zjednodušuji, ona se ve skutečnosti jednou předkompiluje a pak se jí mění syntaktický kontext, ale ve výsledku je pro každé zavolání vnitřní smyčky vytvořená nová subrutina. Kdybych si ji někam ukládal tak bude pokaždé na jiné adrese, atd.) Dá se tomu nějak zabránit? Jistě, vytvořit immutable annonymní subrutinu a Perl je tak chytrý, že ji skompiluje jen jednou.
my $attr = $_; my $successors = $successors{$attr}; $successors and sub { exists $_[0]->{$_} && return 0 foreach predecessors($_[1]); 1 }->($successors, $attr)
Takový kód je pak prakticky stejně rychlý jako do
. Co je na tom zajímavého? Snad jen to, že do
v perlu se tak hezky chová, skompiluje se jen jednou i když obsahuje proměnné v syntaktickém kontextu a je tedy rychlejší než použití annonymního sub
.
Pokud si chcete taky pohrát, tak zde je text kompletního benchmarku:
#!/usr/bin/env perl use strict; use Benchmark qw(:all :hireswallclock); my $count = 100; my %successors = map +($_, {$_ => undef}), 1..$count; sub predecessors {($_[0]-1) .. ($_[0]+1)} sub none (&@) { &{$_[0]} && return 0 foreach @_[1..$#_]; 1 } cmpthese(-2, { 'do' => sub { do {my $attr = $_; my $successors = $successors{$attr}; do { my $res; foreach (predecessors($attr)) { $res = exists $successors->{$_} and last } !$res } } foreach 1 .. $count; }, 'sub' => sub { do {my $attr = $_; my $successors = $successors{$attr}; sub { exists $successors->{$_} && return 0 foreach predecessors($attr); 1 }->() } foreach 1 .. $count; }, 'subimmu' => sub { do {my $attr = $_; my $successors = $successors{$attr}; sub { exists $_[0]->{$_} && return 0 foreach predecessors($_[1]); 1 }->($successors, $attr) } foreach 1 .. $count; }, 'none' => sub { do { my $successors = $successors{$_}; none {$successors->{$_}} predecessors($_); } foreach 1 .. $count; }, 'evalblock' => sub { do {my $attr = $_; my $successors = $successors{$attr}; eval { my $res; foreach (predecessors($attr)) { $res = exists $successors->{$_} and last } !$res } } foreach 1 .. $count; }, 'evalstr' => sub { do {my $attr = $_; my $successors = $successors{$attr}; eval ' my $res; foreach (predecessors($attr)) { $res = exists $successors->{$_} and last } !$res ' } foreach 1 .. $count; }, });
Pro zajímavost jsou doplněny ještě další varianty. Není překvapením, že blokové použití eval
u je stejně rychlé jako do
nebo immutable sub
. Trochu jsem byl zklamán rychlostí při použití krásné elegantní šablonované funkce none
. Tam se vlastně stejně jako při normálním annonymním sub
pokaždé znovu skompiluje první parametr a jestě ke všemu se tato subrutina volá uvnitř foreach
, takže to ve výsledku dopadne hůř. No a nejhorší je eval
stringu, nic divného, že
P.S.: Nakonec jsem se do
úplně vyhnul a použil jednu z vlastností if
, že vrací hodnotu podmínky. No co, aspoň jsem nahlédl do chování perl
u zase o kousek hloub. Ekvivalent shora uvedených kódů pak nakonec vypadá asi takhle:
if (my $successors = $successors{$_}){ my $res; $res = exists $successors->{$_} and last foreach (predecessors($_)); !$res }
Ano, to je celý vnitřek podmínky grepu, ušetřím ještě jednu alokaci proměnné, což je podle mých měření dokonce víc než zavolání sub
Tiskni Sdílej:
do
nerobí to isté, čo sub
. Ako píšu v dokumentácií, Not really a function.
.
do
jednoducho vyhodnotí blok.
sub
vytvorí anonymnú funkciu, ktorej kopíruje kontext (pre ostatných, google: perl closures)