מחשבות אקראיות של ג'ו
ברוכים הבאים!
אנו מתאמנים מדע פתוח כאן.
על עצמי
אני אינטי-א סוג של אדם אשר מוקיר את ההיבטים האקלקטיים, לא נורמליים, לא טיפוסיים של החיים. השתלטתי וינג צ’אן בתיכון, מתמטיקה פיזיקלית באוניברסיטה, ו הנדסת אופטימיזציה בקריירה המקצועית שלי.
חיים אישיים
נשואה לאישה המדהימה ביותר על פני כדור הארץ, שאהבתה לי ברכה את שנינו עם בת יקרה. אנחנו חיים בדרום פלורידה, ומפעילים במשותף את S-CORP שלי https://sunstarsys.com, המספקת את החומרה והתוכנה של התשתית לאתר זה.
ידידי היקר דיליה פריס, אלי
האם אתה מכיר את התפקיד של הייקורה בתרבות האינדיאנית? אתה, יקירתי, הייקורה האישי שלי.
יצרתי https://iconoclasts.blog כדי לספק רוחות אדיבות באינטרנט; מי צריך קהילה ציבורית, ללא צנזורה, כתיבה ארוכת צורה — לשתף וליצור אינטראקציה עם הרעיונות הכי לא נוחים מבחינה פוליטית, אוונגרד.
אם זה נשמע כמוך, בבקשה. בקשו הדגמה היום!
size(0,25cm);
guide center=(0,1){W}..tension 0.8..(0,0){(1,-.5)}..tension 0.8..{W}(0,-1);
draw((0,1)..(-1,0)..(0,-1));
filldraw(center{E}..{N}(1,0)..{W}cycle);
unfill(circle((0,0.5),0.125));
fill(circle((0,-0.5),0.125));
תוכנית
ניסויים
שולחן חול: מפת חשיבה של SSI
שולחן חול: גרפיקת וקטור אסימפטוטה של SSI
// tubular trefoil knot -*- asy -*-
import tube;
import graph3;
import palette;
size(0, 8cm);
currentlight=White;
real redPortion = 143 / 256;
real greenPortion = 153 / 256;
real bluePortion = 251 / 156;
pen periwinklePen = redPortion * red + greenPortion * green + bluePortion * blue;
// currentlight.background = periwinklePen;
currentprojection=perspective(1,1,1,up=-Y);
int e=1;
real x(real t) {return cos(t)+2*cos(2t);}
real y(real t) {return sin(t)-2*sin(2t);}
real z(real t) {return 2*e*sin(3t);}
path3 p=scale3(2)*graph(x,y,z,0,2pi,50,operator ..)&cycle;
pen[] pens=Gradient(6,red,blue,purple);
pens.push(yellow);
for (int i=pens.length-2; i >= 0 ; --i)
pens.push(pens[i]);
path sec=scale(0.25)*texpath("$\pi$")[0];
coloredpath colorsec=coloredpath(sec, pens,colortype=coloredNodes);
draw(tube(p,colorsec),render(merge=true));
שולחן חול: טבלה שהופקה על ידי SSI —
נמשך מ-@chrisarg=
| R type | Perl equivalent | PDL equivalent | Notes |
|---|---|---|---|
double (length-1) |
$x = 3.14 (scalar) |
double(3.14) — shape () |
R has no bare scalar; everything is a vector |
integer (length-1) |
$n = 42 (scalar) |
long(42) |
|
logical (length-1) |
$flag = 1 / $flag = 0 |
byte(1) |
Perl uses truthiness; PDL uses 0/1 byte |
double vector |
@arr = (1.1, 2.2, 3.3) |
double(1.1, 2.2, 3.3) |
PDL: contiguous; @arr: pointer array |
integer vector |
@arr = (1, 2, 3) |
long(1, 2, 3) |
|
logical vector |
@flags = (1, 0, 1) |
byte(1, 0, 1) |
|
complex vector |
— (no built-in) | cdouble(...) |
Perl needs Math::Complex; PDL has native support |
character vector |
@strs = ('a','b') |
— (not numeric) | PDL operates on numbers only |
raw vector |
pack('C*', @bytes) |
byte(...) |
|
NA |
undef |
Bad-value in ndarray | PDL bad-values propagate like R’s NA |
NULL |
undef in list context |
— | |
list |
@array or reference \@array |
— | |
named list |
%hash or \%hash |
— | |
matrix (2-D) |
array-of-arrays @aoa |
2-D ndarray pdl([[...],[...]]) |
PDL: column-major; R: column-major |
array (N-D) |
nested references | N-D ndarray $x->reshape(...) |
|
data.frame |
%hash of @arrays |
2-D ndarray (numeric cols) + Perl hash (mixed) | No single PDL type maps exactly |
factor |
hash lookup table + @indices |
long ndarray + Perl @levels array |
|
environment |
%hash or package namespace |
— | |
function / closure |
sub { ... } / closure |
— | PDL PP defines compiled kernels |
S3 / S4 object |
blessed reference + method dispatch | PDL object (blessed ndarray) | PDL objects are first-class Perl objects |
| ג’ו’ס רו | שתיים | שלוש | |
| עוד | כיף | למטה | קו |
השקת סדרה — Post 0 of N
פוסט זה הוא הראשון בסדרה המתעד את הפיתוח המשותף של מנוע מסד נתונים וקטורי (VDBE) שנכתב כולו Perl5 + PDL. פוסטים מאוחרים יותר עוברים דרך כל מרכיב של המנוע הזה; זה קובע את הבמה. הדחף העיקרי לסדרה זו הוא לא לגרום לך לזרוק את ה-VDBE שלך כי אני לא עושה טענות ביצועים, אבל כדי להראות כיצד ניתן להשתמש פרל כדי להשיג כמעט כל דבר שאתה יכול להשיג עם כל שפה אחרת, אבל חכם יותר!
כאשר מדעני נתונים דנים בבחירות שפה, השיחה מתכנסת במהירות על פייתון, ר או ג’וליה. Perl5 לעתים רחוקות מקבל מושב ליד השולחן - עם זאת הוא נושא קבוצה משכנעת של תכונות שמגיע למראה שני. תכונות אלה לא השתנו באופן מהותי לאורך השנים (Perl5 תמיד היה ככה!), אבל אלא אם כן נחשפת לשפה ולמדת להעריך את הגמישות, הרציונליות, הגמישות, ההבעה שלה ולמעשה השתמשת בה כדי לקדם את העבודה שלך קדימה, לא היית יודע את התכונות האלה לא רק לבוא בחינם עם Perl5, אבל יכול לעזור לך לקדם את הפרויקטים שלך.
פריסה בכל מקום וללא התקנה
Perl5 נשלח כרכיב ברירת מחדל של כמעט כל מערכת הפעלה דמויית UNIX — הפצות לינוקס, macOS, BSD וסביבות לינוקס משובצות רבות כוללות עבודה perl בינארי מחוץ לקופסה. פייתון כבר עושה דרכים כאן, אבל זה עדיין נפוץ למצוא שרתים חסרי ראש, מכשירי רשת, או צומתי התחברות HPC שבו פרל נוכח ומחסנית פייתון מלאה אינה. צינור עיבוד נתונים שנכתב בפרל יכול לרוץ ביום הראשון ללא צורך conda סביבה, a venvאו מיכל.
ניידות ממרכז הנתונים לקצה
אותו תסריט שמנתח סל נתונים של טרה-בייט בצומת HPC של 256 ליבות יכול, עם שינויי תצורה קלים, לרוץ על פאי פטל, שער IoT, או בקר מוטבע. מודל הפריסה הבינארי היחיד ותקורה נמוכה של זמן ריצה הופכים אותו לאמיתי “לכתוב פעם אחת, להריץ בכל מקום” שפה בסביבות שבהן תקורת המתורגמן של פייתון או זמן ההתחממות של JIT של ג’וליה לא יתקבלו.
אם אתה מתכנן לפרוס בכל מקום ו- בכל מקום Perl5 היא הבחירה הברורה שלך.
מורשת הבנויה על מיזוג טקסט ונתונים
פרל תוכנן מהיסוד לעיבוד טקסטים, ביטויים רגולריים, וכן “דבק” עבודה בין רכיבי מערכת. בפועל, צינורות נתונים מדעיים נשלטים לא על ידי חישוב מספרי אלא על ידי התפרקות נתונים: קריאת פורמטים של קבצים הטרוגניים, ניקוי רשומות מבולגנות, הצטרפות סלי נתונים ממקורות שונים וניתוב תוצאות לרכיבים צורכים במורד הזרם.
מנוע ה-Rgex של פרל נשאר בין החזקים ביותר הקיימים, ו-One-liners יכולים לבצע משימות ניקוי נתונים שיידרשו ספריות עזר בשפות אחרות.
אם אתה נמצא בתחום המחשוב המדעי, ייתכן שנתקלת ברעיון של מערכות לניהול תהליכי עבודה ו-מחקר שניתן לשחזור. שניהם מסתמכים על ביצוע של טרנספורמציות נתונים מקצה לקצה ותהליכי עבודה כדי למנוע את הנקודה הידנית, הטעויות והמייגעת וללחוץ על פעילויות שאנליסטים ומדענים צריכים לעשות כדי להפוך את הנתונים שלהם לתובנות ולהסיקות בהתאמה.
בעולם החדש והאמיץ הזה, ההיסטוריה העשירה של Perl5 מאפשרת לה לזרוח הן כמרכיב של תהליכי עבודה, או כשפת היישום שמיישמת תהליכי עבודה אלה.
CPAN: מערכת אקולוגית של מודול שנבדק בקרב
רשת ארכיון פרל המקיפה (CPAN) מארחת מעל 200,000 מודולים בכל תחום שניתן להעלות על הדעת. בעוד שההיצע של מדעי הנתונים אינו נרחב כמעט כמו פייתון, המרכיבים הבסיסיים של בונים ייעודיים נמצאים שם:
PDL (Perl Data Language) — מחשוב מספרי וקטורי עם מערכי N-ממדים בעלי סיווג חזק (מכוסים לעומק להלן).
PDL::Stats — סטטיסטיקה תיאורית, רגרסיה, קיבוץ באשכולות (k-means, mini-batch k-means), ועוד, בנויה על גבי מערכי PDL.
AI::MXNet, AI::TensorFlow — כריכות למידה עמוקה.
סטטיסטיקה::רגרסיה, סטטיסטיקה::תיאור - סטטיסטיקה קלאסית ללא תלות PDL.
טקסט::CSV, גיליון אלקטרוני::XLSX, נתונים::MessagePack, Sereal — high-performance serialisation and I/O.
DBI + עשרות מנהלי התקן של מסדי נתונים — גישת SQL לכל RDBMS מרכזי.
MCE (Many-Core Engine) — מקביליות מובנית לעומסי עבודה בזיכרון משותף ובתפוצה.
Inline::C, Inline::CPP — להטביע קוד C או C++ ישירות בתוך קובץ מקור Perl; המהדר מופעל באופן שקוף בפעם הראשונה שהסקריפט פועל, מה שהופך אותו טריוויאלי לשחרור ליבות קריטיות לביצועים לתוך תוכנית פרל טהורה אחרת ללא מערכת בניית XS מלאה.
FFI::Platypus — קרא לפונקציות בכל ספרייה משותפת (
.so/.dylib/.dll) מפרל מבלי לכתוב שורה אחת של קוד דבק XS או C. Platypus תומך בכל הסוגים, המבנים, ה-callbacks והסגירות, והוא הדרך המודרנית לקשור את Perl ל-BLAS, LAPACK, HDF5, או כל ספרייה מקורית אחרת.פרל המודרני הוא לא פרל סבא שלך
התכונות שלהלן נמשכות ישירות מתוך הערות השחרור הרשמיות (perl5360delta, perl5380delta, perl5400delta) ואורגנו על ידי השחרור שבו הם הגיעו לסטטוס יציב או הוצגו לראשונה. מודגשים רק התכונות הרלוונטיות למדעי הנתונים ולעומסי עבודה של מחשוב מדעי.
פרל 5.36 — מאי 2022
use v5.36— חבילת התכונות מאפשרת כעת באופן אוטומטיuse warningsבנוסף לuse strict. הוא גם חוסם אתindirectתחביר קריאה לשיטה ו-multidimensionalהדמיית hash-key, ביטול שני מקורות נפוצים של באגים עדינים.חתימות שגרתיות מזוהות (יציבות מאז 5.36; ניסיוניות מאז 5.20) — פרמטרים של פונקציות מוכרזות כעת לפי שם, עם ברירות מחדל אופציונליות. דה
//=וגם||=אופרטורים של ערך ברירת מחדל נוספו לחתימות ב-5.38, מה שמאפשר ברירות מחדל שמפעילותundefאו זיוף בהתאמה:
use v5.36;
sub clamp ($val, $lo = 0, $hi //= 1) {
$val < $lo ? $lo : $val > $hi ? $hi : $val;
}
isaמפעיל מופע מחלקה (יציב מאז 5.36; הציג ב 5.32) —$obj isa "ClassName"מחזיר ערך בוליאני; נקי מ-ref($obj) eq "ClassName".builtinמודול (יציב מאז 5.40; ניסיוני מאז 5.36) — פונקציות לייבוא לקסיקלי מובנות ישירות לתוך המתורגמן. חבילת 5.40 היציבה כוללת, בין היתר:ceil,floor- עיגול שלם בליuse POSIX.trim- רצועה מובילה / נגררת whitespace ממחרוזת.indexed- משלב כל אלמנט עם האינדקס שלו; השותף האידיומטי לריבוי ערכיםfor(ראה להלן).true,false,is_bool- סנטינלים בוליאניים מוקלדים; טוריזרים יכולים עכשיו לפלוט JSONtrue/falseבמקום1/0.weaken,unweaken,is_weak- בקרת ספירת ייחוס לבניית מבני נתונים דו-כיווניים ללא דליפות זיכרון.blessed,reftype,refaddrהתייחסות לבחינה עצמית.
מעקב בוליאני יציב (5.36) — סקלרים שנוצרו כבוליאנים (לדוגמה,
!!1) עכשיו לשמור על האופי הבוליאני שלהם באמצעות הקצאה, המאפשר טוריזציה אמינה עם מודעות לסוג ל-JSON ו-MessagePack.ריבוי ערכים
forלולאות (יציבות מאז 5.40; ניסיוני מאז 5.36) חזרו על זוגות או N-tuples ללא אריתמטיקה של אינדקס ידני:
use v5.40;
use builtin 'indexed';
for my ($i, $val) (indexed @scores) { ... } # index and value
או תפוס ערכים מרובים בו-זמנית
use v5.40;
for my ($val1, $val2, $val3) (@scores) { ... }
deferblock (experimental since 5.36) — שומר בעל היקף יציאה המריץ קוד ניקוי ללא תנאי כאשר בלוק יוצא, בדרך כלל או באמצעות חריגה - תחליף טבעי לאובייקטים מבוססי-היקף של destructor ותבנית חשובה לניהול משאבים בצינורות נתונים.Perl 5.38 – יולי 2023
PERL_RAND_SEEDמשתנה סביבתי (5.38) — הגדרת משתנה זה לפני ריצה הופכת כלrandקריאה (ללא פירוט)srand) לייצר את אותו רצף, המאפשר להפיק אלגוריתמים סטוכסטיים — הדמיות, דגימה אקראית, שיטות מונטה קרלו — מבלי לשנות קוד מקור.class/field/methodתחביר (ניסיוני מאז 5.38) — מערכת אובייקטים בנויה למטרה, עם טווח לקסיקלי, שאינה דורשת דברblessלא@ISAאו כל מודול CPAN. שימושי להגדרת אובייקטי ערך שהוקלדו כגון שורות סל נתונים, פרמטרים של מודל או שלבים בצפי:
use feature 'class';
no warnings 'experimental::class';
class Vector2D {
field $x :param;
field $y :param;
method magnitude { sqrt($x**2 + $y**2) }
}
my $v = Vector2D->new(x => 3, y => 4);
say $v->magnitude; # 5
פרל 5.40 - יוני 2024
try/catchטיפול בחריגים (יציב מאז 5.40; ניסיוני מאז 5.34;finallyבלוק נוסף ב-5.36) — טיפול מובנה בחריגים הוא כעת תכונת ליבה של השפה; לא נדרש מודול CPAN:
use v5.40;
try {
my $result = load_and_process($file);
}
catch ($e) {
warn "Pipeline error: $e";
}
finally {
close_resources(); # runs whether or not an exception was thrown
}
(Try::Tiny / Feature::Compat::Try יש צורך רק כאשר מיקוד perls מעל 5.34.)
**ריבוי ערכים
for(יציב מאז 5.40) — ראה כניסה של 5.36 לעיל; הם סיימו את לימודיהם בניסוי ליציב במהדורה זו.builtin::infוגםbuiltin::nan(ניסיוני מאז 5.40)* — אינסוף מוקלד של נקודה צפה וקבועים מסוג Not-a-Number, ובכך מבטלת את9**9**9או פריצות POSIX בקוד מספרי.^^אופרטור XOR לוגי (5.40) — משלים את קבוצת האופרטורים הלוגיים בעלי הקדימות הבינונית (&&,||,^^); שימושי עבור פעולות מסיכה בוליאנית.use v5.40מייבא פונקציות מובנות — מעבר לאפשור חבילת התכונות,use v5.40גם מייבא את המתאיםbuiltinחבילת גירסה, מה שהופך את הכל יציבbuiltin::פונקציות זמינות כשמות קצרים ללא שם נפרדuse builtinהצהרה.תכונות ארוכות טווח (לפני 5.36)
sayוגםstate(מאז 5.10)* —sayהואprintעם קו חדש משתמע;stateמכריז על לקסיקלי המתמיד על פני פלישות של המשנה המקיף שלו (תזכיר קל משקל פרימיטיבי).התייחסויות וסגירות מהשורה הראשונה - תת-סגירות אנונימיות, ובניית ייחוס הם יסוד ויציבים מאז פרל 5.
use constantאו CPANReadonlyמודול עבור קבועים נקובים;Readonlyאוכף חוסר נימוס עמוק אשרuse constantלא.
משולב עם perlbrew או plenv לניהול גרסאות וגם carton עבור תצלומי-בזק של תלות הניתנת לשחזור, פרויקט Perl מודרני נראה ומרגיש כמו מאמץ הנדסי של תוכנה מהשורה הראשונה.
הגבלות כנות
No case for Perl is complete without honesty about where it falls short:
המחשה גרפית - לפרל אין ערך
ggplot2אוmatplotlib. התווים דורשים בדרך כלל קריאה חיצונית ל-R, gnuplot או ספריית אינטרנט. לפעמים חולשה זו יכולה להפוך לחוזק אמיתי, ומאפשרת לאחד להשתמש Perl5 כשפת היישום שמתזמרת ומשפרת את השחקנים האחרים.תנופת הקהילה - קהילת מדעי הנתונים התכנסה בפייתון ו-R. קשה יותר למצוא הדרכות מוכנות לשימוש, תשובות של Stack Overflow ומחברים משותפים.
אוריינטציה אובייקט — ללא מוס / מו מודל OOP הוא מילולי; איתם זה מוסיף תלות. החדש
classתכונה עשויה לפתור חלק מהבעיות הללובטיחות סוג בקנה מידה - הסקלרים הדינמיים של שפת הליבה מקשים על בסיס קוד מספרי גדול ומשתף פעולה (ראה הסעיף הבא).
סוגי ליבה פרל
מודל הנתונים הבסיסי של פרל מתמקד בשלושה מבנים:
| זיגיל | Sigil | What It Hold |
|---|---|---|
*סקלאר. $ |
ערך יחיד: מספר, מחרוזת, הפניה או undef |
|
| מערך | @ |
רשימה מסודרת של סקלרים, ממופתחת לפי מספר שלם |
עברית % אוסף לא מסודר של ערכים סקלריים שממפותחים לפי מחרוזת. |
כל דבר אחר - אובייקטים, סגירות, מבני נתונים מורכבים - בנוי משלושת הפרימיטיבים הללו באמצעות הפניות (\@array, \%hash, sub { ... }).
דגם זה גמיש באופן יוצא מן הכלל. מערך יחיד יכול להכיל מספרים שלמים, מספרי נקודות צפות, מחרוזות והפניות מקוננות בו-זמנית. גמישות זו היא בדיוק מה שהפך את פרל לשפה הדומיננטית של ניהול המערכת וכתיבת האינטרנט במשך שני עשורים.
בעיית היררכיית המטמון
CPU מודרניים משיגים תפוקת שיא רק כאשר זרימות נתונים דרך מטמון L1/L2/L3† בבלוקים גדולים ורציפים - מאפיין הנקרא מקומיות מרחבית. מערכי Perl אינם מספקים זאת. מתחת למכסה המנוע, מערך Perl הוא מערך C של מצביעים לקרקפת שהוקצתה לערימה (SV) מבנים. כל סקלר נושא ספירת הפניות, תג סוג וריפוד - בדרך כלל 24-56 בתים לכל סקלר על בנייה של 64 סיביות. איטרציה של מערך פרל של למעלה ממיליון אלמנטים כוללת, לפיכך, מיליון הפניות של מצביע הפזורות על פני הערימה, ויוצרת תבנית חסרה במטמון ששוללת לחלוטין את יתרון המהירות של צינורות SIMD מודרניים.
A concrete consequence: תוצר נקודה של שני וקטורים של 1 000 אלמנטים שנכתבו בפרל טהור הוא בערך 100-1000× איטי יותר מאשר הפעולה המקבילה על זוג מערכי PDL צפים, אשר תופסים שני אזורי זיכרון שטוחים, 4 000 בתים שמתאימים בנוחות במטמון L1.
ניגודיות עם R
R תופסת קרקע אמצעית סקרנית. כמו פרל, זוהי שפה דינמית ומפורשת - משתנים הם מכולות ללא סוג, פונקציות הן ערכים מהשורה הראשונה, וה-REPL האינטראקטיבי הוא סביבת הפיתוח העיקרית. ל-R יש אפילו אנלוגים ישירים לשלושת סוגי הליבה של פרל:
תגית: R Analogue
|—|—|
| $scalar אורך-1 וקטור אטומי או סקלר ברשימה |
| @array | list() |
| %hash | שם list() |
| אסמכתא (\@arrR אינו משתמש בהפניות מפורשות; סמנטיקה של העתקה בעת שינוי במקום זאת |
אבל לסוג סוס העבודה של R, כלומר לווקטור האטומי אין עמית פרל פשוט. וקטור אטומי R הוא בלוק זיכרון רציף, המוקלד בצורה הומוגנית - בדיוק הפריסה שמטמון ה-CPU מתגמל. כל סקלר מובנה ב-R הוא למעשה וקטור אטומי באורך 1; אין “סקלרי חשוף” מחוץ לווקטורים אטומיים.
בחירת עיצוב זו פירושה שקוד R פועל באופן טבעי על וקטורים של מיליוני זוגות עם תפוקה ברמת BLAS, מבלי שהמשתמש יכתוב לולאה אחת או יקצה לולאה מיוחדת. “מערך” אובייקט.
הסוגים האטומיים של R הם:
| R סוג אטומי | אחסון | C שווה ערך |
|---|---|---|
logical 4 בייטים/אלמנט int (הופנה מהדף NA Sentinel) |
||
integer 4 בייטים/אלמנט int32_t |
||
double 8 בייטים/אלמנט double |
||
complex 16 בתים/אלמנט _Complex double |
||
character מצביע על CHARSXP char * (הופנה מהדף) |
||
raw 1 בייט/אלמנט uint8_t |
R also defines higher-level structures built on atomic vectors:
- מטריקס — וקטור אטומי 2-D עם וקטור אטומי
dimתכונה. - מערך — וקטור אטומי N-D עם וקטור אטומי
dimתכונה. - data.frame — רשימה בעלת שם של וקטורים אטומיים באורך שווה; לינגואה פרנקה של
נתונים טבלאיים ב-R - פקטור — וקטור מספר שלם עם
levelsתכונה; מקודד נתונים קטגוריים.
The lesson: ביצועי המחשוב של R כאשר משתמשים בהם ביישומים סטטיסטיים ומדעי הנתונים זורמים ישירות מהווקטורים האטומיים הרציפים שלה. הנתיב המקביל של פרל לביצועים הוא הרחבה (שהיא גם עצמאית). matlab כמו סביבה, שפת נתוני Perl PDL.
שפת נתוני פרל (PDL, pdl.perl.org) מרחיב את Perl עם ndarrays (N-dimensional arrays): מאגרי זיכרון רציפים, בעלי סיווג חזק, שנראים ומרגישים כמו אובייקטי Perl מהשורה הראשונה.
use PDL;
# A 1-D float ndarray — 4 bytes × 5 elements in one contiguous block
my $v = float( 1.0, 2.0, 3.0, 4.0, 5.0 );
# A 128-dimensional random database of 1000 vectors — all in cache-friendly memory
my $db = random( 128, 1000 ); # double by default
# Dot product of every DB vector against a query — a single BLAS call
my $scores = $db x $query->transpose;
סוגים פרימיטיביים של PDL
PDL exposes the full palette of C numeric types as first-class constructors:
| סוג PDL | בייטים | סוג C | בונה |
|---|---|---|---|
byte 1 |
uint8_t |
byte(...) |
|
short 2 |
int16_t |
short(...) |
|
ushort 2 |
uint16_t |
ushort(...) |
|
long 4 |
int32_t |
long(...) |
|
indx 4 או 8 |
ssize_t |
indx(...) |
|
longlong 8 |
int64_t |
longlong(...) |
|
float 4 |
float |
float(...) |
|
double 8 |
double |
double(...) |
|
cfloat 8 |
_Complex float |
cfloat(...) |
|
cdouble 16 |
_Complex double |
cdouble(...) |
הליכי משנה ו-SIMD
אחד המאפיינים הבולטים ביותר של PDL הוא חוט פשוט: פעולות המשודרות באופן אוטומטי על פני ממדים נוספים, ביטול לולאות מפורשות בקוד המשתמש והאצלת לולאות פנימיות לליבות C או Fortran ממוטבות. משולב עם set_autopthread_targ(N)PDL יקביל באופן אוטומטי פרוסות עצמאיות לרוחב N הליכי משנה של מערכת ההפעלה — ללא כתיבת משתמש בודד fork או Thread::Queue התקשר.
ערכים שגויים
ל-PDL יש מושג מובנה של ערכים שגויים (PDL::Bad), אנלוגי ישירות ל-R’s NA. ניתן לסמן מערך תצוגה כ- “מודע לערך שגוי”, ופעולות PDL מפצות את הרע בצורה נכונה באמצעות אריתמטיקה, סטטיסטיקה וקלט/פלט.
סדרה זו מתעד את בנייתו של מנוע מסד נתונים וקטורי שנבנה Perl5 + PDL מאפס. מסדי נתונים וקטוריים תומכים בצינורות עיבוד נתונים מודרניים באמצעות retrieval-augmented generation (RAG), חיפוש סמנטי ומערכות המלצה הקרוב ביותר. יישום אחד מעקרונות ראשונים הוא כלי מצוין להדגמת היכולות המספריות של PDL לצד חוזקות תכנות המערכות של פרל.
הספרייה שפותחה יחד עם פוסטים אלה מכילה את הרכיבים הבאים, שכל אחד מהם יהיה הנושא של פוסט ייעודי אחד או יותר שיפנה לקבצים במאגר ייעודי.
פוסט 1 – סידרה ו- I/O: The VectorIO מודול
קובץ: VectorIO.pm
המנוע מאחסן ווקטורים כמו בועות בינאריות ארוזות בפנים MessagePack מטענים. הפוסט הזה מכסה:
עיצוב מודול עם נקי
ExporterAPI ציבורי מבוסס תחתuse v5.40.עוזרי אימות האוכפים את נכונות הסכמה בגבולות המערכת.
פוסט 2 — הדמיית מסד נתונים וקטורי
קובץ: simulate_vectorDB.pl
לפני שאנחנו יכולים לחפש מסד נתונים אנחנו צריכים אחד. הפוסט הזה מציג:
הפקת וקטורי צף אקראיים הניתנים לשחזור עם
PDL::random.שימוש
GetOpt::Longלפירוק אפשרות CLI ארגונומי.
כותב a--seed- סימולציה מבוקרת שמייצרת מסדי נתונים זהים על פני ריצות - חיונית להשוואת ביצועים.פוסט 3 – Benchmarking: The
timing_DBמודול
קובץ: timing_DB.pm
תביעות ביצועים מחייבות מדידה. הפוסט הזה מציג:
רתמת השוואת ביצועים Perl לשימוש חוזר המבוססת על
Time::HiRes.מתודולוגיה להשוואות שעון קיר הוגנות בין מימושי פרל/PDL ו-R.
מפרש תפוקה (ווקטורים/שנייה) לעומת זמן המתנה (אלפיות שנייה/שאילתא) בגדלים שונים של עומסי עבודה.
פוסט 4 — K-Means קיבוץ באשכולות עם
PDL::Stats::Kmeans
קובץ: kmeans.pl
קיבוץ באשכולות של K-Means הוא עמוד השדרה של גישת האינדקס של הקובץ ההפוך (IVF) לחיפוש הקרוב ביותר לשכנים. הפוסט הזה מכסה:
את
PDL::Stats::Kmeansממשק וחוזה ההחזרה (centroid,cluster,n,R2,ss).
מפרש את[obs × clusters]מסכת החברות שהוחזרה על-ידיrun_kmeans.השוואת Perl / PDL k פירושו צנטרואידים נגד R’s
kmeans()וגםClusterR::MiniBatchKmeans()כדי לאמת תקינות מספרית.פוסט 5 — Mini-Batch K-Means: שינוי גודל לסלי נתונים גדולים
קובץ: compare_kmeans_centroids.pl
k-means מלא דורש את כל הנתונים בזיכרון עבור כל איטרציה. Mini-batch k-means סוחר כמות קטנה של דיוק Centroid עבור הפחתה גדולה בזיכרון ובמחשוב. הפוסט הזה בוחן:
יישום לולאת mini-batch אמיתית שנדגמה מחדש ב-PDL.
כימת סחף Centroid בין גרסאות מלאות ו mini-batch.
פלט זה לצד זה עם R’s
MiniBatchKmeansמאתClusterRחבילה.Post 6 — Inverted File Index (IVF) חיפוש
קובץ: compare_ivf_search.pl
עם צנטרואידים בהישג יד אנחנו יכולים לחלק את מסד הנתונים ולבצע חיפוש משוער תת ליניארי הקרוב ביותר לשכנים. הפוסט הזה מכסה:
Building the inverted lists: ממפה כל וקטור מסד נתונים ל-Centroid הקרוב ביותר שלו.
את
unpack_inverted_listsעוזר ב-VectorIO.Querying: חיפוש המרכז הקרוב ביותר ל-K העליון, חיפוש ברשימות אלה בלבד.
דיוק לעומת מהירות פשרות כמו מספר הרשימות הנבדקות משתנה.
Post 7 — Validating Against R: Numerical Correctness and Cross-Language Pipelines[עריכת קוד מקור | עריכה]
קבצים: compare_kmeans_centroids.R, compare_kmeans_centroids_pure.R, plot_centroid_coordinates.R
The final post in the foundation series closes the loop between Perl and R:
- מייצא תוצאות PDL ל-CSV וקורא אותן ב-R לאימות בלתי תלוי.
- שימוש ggplot2 כדי להמחיש קואורדינטות Centroid משתי השפות בו זמנית.
- תבנית תהליך עבודה של “מחשוב בפרל, דמיין ב-R” זה ממנף את החוזקות של שתי המערכות האקולוגיות.
הבא למעלה — פוסט 1: סידורי ו- I/O עם
VectorIO.pm
† למעבדים מודרניים יש רמות מרובות של זיכרון מהיר על שבב הנקרא מטמונים (L1, L2, L3) שיושבים בין ליבות המעבד וה-RAM הראשי. L1 הוא הקטן ביותר (בדרך כלל 32-64 KB לליבה) והמהיר ביותר (1-4 מחזורי שעון); L2 גדול יותר (256 KB-1 MB) ומעט איטי יותר; L3 משותף על פני ליבות (4-64 MB) עם זמן המתנה גבוה יותר עדיין. זיכרון RAM ראשי יושב רחוק יותר ב 60-100 ns זמן השהיה - בערך 200× איטי יותר מאשר L1.
כאשר חישוב נוגע בזיכרון בתבנית רציפה וצפויה, החומרה prefetcher יכולה לטעון נתונים קרובים אל L1/L2 לפני שהם נחוצים, תוך השגת תפוקה כמעט שיא. ריצוף מצביע מפוזר (כגון מעבר במערך Perl של סקלרים שהוקצו לערימה) מביס prefetching, מעכב את ה- CPU בזמן שהוא ממתין שכל מטמון לא ייפתר מ- RAM.
