Po 9 týdnech vývoje od vydání Linuxu 6.8 oznámil Linus Torvalds vydání Linuxu 6.9. Přehled novinek a vylepšení na LWN.net: první a druhá polovina začleňovacího okna. Později také na Linux Kernel Newbies.
Byla vydána verze 0.2.0 v Rustu napsaného frameworku Pingora pro vytváření rychlých, spolehlivých a programovatelných síťových systémů. Společnost Cloudflare jej letos v únoru uvolnila pod licencí Apache 2.0.
Open source RDP (Remote Desktop Protocol) server xrdp (Wikipedie) byl vydán ve verzi 0.10.0. Z novinek je vypíchnuta podpora GFX (Graphic Pipeline Extension). Nová větev řeší také několik bezpečnostních chyb.
Rocky Linux byl vydán v nové stabilní verzi 9.4. Přehled novinek v poznámkách k vydání.
Dellu byla odcizena databáze zákazníků (jméno, adresa, seznam zakoupených produktů) [Customer Care, Bleeping Computer].
V lednu byl otevřen editor kódů Zed od autorů editoru Atom a Tree-sitter. Tenkrát běžel pouze na macOS. Byl napevno svázán s Metalem. Situace se ale postupně mění. V aktuálním příspěvku Kdy Zed na Linuxu? na blogu Zedu vývojáři popisují aktuální stav. Blíží se alfa verze.
O víkendu 11. a 12. května lze navštívit Maker Faire Prague, festival plný workshopů, interaktivních činností a především nadšených a zvídavých lidí.
Byl vydán Fedora Asahi Remix 40, tj. linuxová distribuce pro Apple Silicon vycházející z Fedora Linuxu 40.
Představena byla služba Raspberry Pi Connect usnadňující vzdálený grafický přístup k vašim Raspberry Pi z webového prohlížeče. Odkudkoli. Zdarma. Zatím v beta verzi. Detaily v dokumentaci.
Byla vydána verze R14.1.2 desktopového prostředí Trinity Desktop Environment (TDE, fork KDE 3.5). Přehled novinek v poznámkách k vydání, podrobnosti v seznamu změn.
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)