נצפה לאחרונה
נצפה לאחרונה

ביצועי יישום

[DRAFT] עודכן לאחרונה מאת Joe Schaefer ב-יום ג׳, 28 אפר׳ 2026    מקור
 

מפתחים רבים נופלים למלכודת של חשיבה אופטימיזציה ביצועים היא על הפיכת כל שורה של קוד יעיל ככל האפשר.או לבחור לכתוב את כל האפליקציה שלהם בשפת התכנות המהירה ביותר שהם יכולים למצוא.

זה בעצם ההיפך. אתה מתחיל באילוצים הארכיטקטוניים של היישום, ומשתמש בהם כדי לתחקר מטה אל שנצפה “איטי ביותר” חלק מהתוכנית. היישום של חלק זה מנחה את כל אפשרויות הביצועים האחרות שעליך לעשות. כל דבר שאינו איטי כמו זה, לא צריך להיות אופטימיזציה יותר. במקום זאת, התמקדו בביטוי האנושי ובפשטות ובבהירות של היישום, לקוראים שאינם מומחים על פני SSDLC של התוכנה, עבור שאר הקוד של התוכנית שלך.

אתה יכול לחזור על הספר הזה, אבל מעולם לא הייתי צריך ללכת מעבר 3 איטרציות בקריירה המקצועית שלי.

אז קדימה ולהשתמש בשפת תכנות אלגנטית כמו Python3 או כתב יד/כתב סוגים, ולתת למומחי הנושא (SME) שם בחוץ בעולם הקוד הפתוח לתת לך עוצמה ג/ג++ קישורים טבעיים לצרכים המיוחדים שלך. שום דבר שאתה עושה עבור לוגיקה עסקית לא צריך יותר מהירות מאשר כל שפת תכנות דינמית יכולה לתת לך מחוץ לקופסה.

אפילו סקריפט bash נטול תלות הוא פתרון מעשי עבור משימות בסיסיות רבות. הנה אחד שכתבתי עבור Augmented Reality קפיצת קסם לפני שנים, כדי להחליף מגושם OpenGrok שירות עם משהו שממנף מקבילות עם ריבוי מעבדים xargs - זכאים, ותומך מוקד ספקים חיפוש פשוט אמק/וים כריכות.

https://github.com/joesuf4/home/blob/wsl/bin/pffxg.sh

התסריט הזה הוא בסדר גודל מהיר יותר מהחשודים הרגילים ב-GitHub, שנכתבו כולם בשפות תכנות מהודרות. אבל על ידי זיהוי צוואר הבקבוק המדויק ב באש (הופנה מהדף High Volume) מזלג+ביצוע שיחות באמצע, ושימוש xargs במקום זאת, אתה מקבל תסריט שנראה הרבה כמו זה, עם אלגוריתם הליבה מיושם 10 שורות של מעטפת.

היא גם משתמשת בקהילת הקוד הפתוח של SME בצורה חכמה, במקום בדרך האחרת. “grep רקורסיבי מסונן” מימושים ב-GitHub עשו זאת. במקום לאמץ ולתחזק באופן פנימי את היישום (המורכב) שלי חיפוש, xargs, וגם ירוקcolor, אני פשוט עושה שימוש חוזר בקובצי ההפעלה שהותקנו מראש בעוד SME‘s כבר מושלמים במשך עשרות שנים כפי שהם, ובעיקר משתמשים במעטפת נבנתה למשך שאר התקופה. אני לא צריך לשלוט ביישומים שלהם, פשוט לעשות שימוש חוזר שלהם ממשק לקוחש. אני אפילו לא רוצה לשלוט בהם, זה שלהם bailiwick. נתוני ביצועים חשובים רק כאשר הם כמה שניות או יותר, בהתחשב בתרחישי השימוש הצפויים (האנושיים) של היישום.

שאר התסריט מנצל בעיקר מעטפת bash מובנית, אשר מיושמים טהור ג על ידי bash developer.

כדי לראות את ההפך, שבו הכל נעשה בתוך הבית, microoptimized לחלוטין, ועדיין לא יכול לנצח את התסריט הזה עם אפשרויות חיפוש ברירת מחדל, ואין מערכת מטמון זמין, הנה דוגמה מצוינת https://github.com/BurntSushi/ripgrep

רק כדי למשוך את #performance #benchmark הראשון מדף זה, ולהגדיל אותו מגודל עץ לדוגמה צעצוע (מקורות ליבה לינוקס), לעץ הטרוגני שהוא 23GB(הריצה הטובה ביותר לאחר 3 איטרציות; שפה=en_US.UTF-8)

    % du -sh .
    23G .
    % time rg -uuniw '[A-Z]+_SUSPEND' | wc -l
    6259
    rg -uuniw '[A-Z]+_SUSPEND' 9.46s user 16.08s system 261% cpu 9.759 total
    wc -l 0.00s user 0.07s system 0% cpu 9.759 total
    % time pffxg.sh -- -wnE '[A-Z]+_SUSPEND' | wc -l
    5855
    pffxg.sh -- -wnE '[A-Z]+_SUSPEND' 16.66s user 2.68s system 429% cpu 4.501 total
    wc -l 0.00s user 0.00s system 0% cpu 4.501 total

זה די טיפשי למיקרו-אופטימיזציה של משהו שקשור עמוק למצב של מטמון מערכת הקבצים של הליבה לחיפוש שלך. הווריאציה בתזמוני הביצועים נשלטת על ידי מהירות הגישה לגוף תוכן הקבצים, וזה סדר גודל רלוונטי יותר מכל גורם אחר לתוצאות הסיום. להיות על NVMe עוזר, אבל שום דבר בחלל הזה פועם זיכרון עצמו.

זו הסיבה שיש מטמון בזיכרון, דחוס עבור מאגר גדול של קבצים, יתייצב את תזמון הביצועים. זה מפתיע שאף אחד אחר לא חשב שזה מספיק חשוב כדי לתמוך.

הורד את #performance #benchmark השני מהדף, והגדל אותו כמו קודם (אותו הדבר) 23GB עץ:

    % time rg -tc -uuuiwn '[A-Z]+_SUSPEND' | wc -l
    5629
    rg -tc -uuuiwn '[A-Z]+_SUSPEND' 3.51s user 1.71s system 1141% cpu 0.457 total
    wc -l 0.00s user 0.05s system 11% cpu 0.457 total
    % time LANG=C pffxg.sh --cache /tmp/pffxg-$USER --workers 32 --cc -- -wE '[A-Z]+_SUSPEND' | wc -l
    5628
    LANG=C pffxg.sh --cache /tmp/pffxg-$USER --workers 32 --cc -- -wE  3.14s user 0.88s system 1055% cpu 0.381 total
    wc -l 0.00s user 0.00s system 0% cpu 0.381 total

כוונון pffxg.sh הוא עדיין מהיר יותר, למרות כל העבודה לשים לתוך microoptimizing ripgrep עבור זה ג-קובץ lookup.

הדרך שבה השתמשתי בתסריט הזה AOSP היה אמור לתזמן a הסכם רכש חוזר סנכרון ועוקב pffxg.sh **lz4-מטמון דחוס מוגדר מראשtmpfsלרוץ כל בוקר לפני העבודה סרטנים), עם PFFXG_CACHE=... מוגדר ב- ~/.pffxg.conf קובץ. כך כל pffxg.sh הפעלות שרצתי במהלך יום העבודה ישתמשו במטמון הדחוס ב- tmpfsלא משנה מה היה מצב מטמון מערכת הקבצים של הליבה באותו זמן.

.25M מיקום בין ריפגרף וגם ugrep. 632 מיקום עבור pffxg.sh. טיפש.

כי זו תוכנית כל כך קטנה, pffxg.sh יכול לתת לך ווים חזקים לתוך הפנימי שלה עם כמעט אפס מאמץ. אפילו ירוקcolor הפקודה עצמה ניתנת להתאמה אישית: כל פקודה שעליך להפעיל על מאגר קבצים נבחר, שיכול לקבל רשימה של שמות קבצים המצורפים לסוף הטיעונים שלה, היא משחק הוגן. הנה a “סה”כ ספירת שורות ב- MiLOC“ תגית: Linux Kernel Git Repo

    % time find *-type f | xargs wc -l | awk '{ $2 == "total" {a+=$1} END {print a/1024**2}'
    28.451
    find *-type f 0.00s user 0.06s system 2% cpu 2.733 total
    xargs wc -l 0.53s user 1.02s system 54% cpu 2.853 total
    awk '$2 == "total" {a+=$1} END {print a/1024**2}' 0.23s user 0.59s system 28% cpu 2.853 total

% time pffxg.sh --workers 8 --cmd wc --all -- -l | awk '{$2 == "total" {a+=$1} END {print a/1024**2}'
    28.4506
    pffxg.sh --workers 8 --cmd wc --all -- -l 0.92s user 0.66s system 826% cpu 0.192 total
    awk '$2 == "total" {a+=$1} END {print a/1024**2}' 0.02s user 0.00s system 11% cpu 0.192 total

ריפגרף גרסה:

    % time rg -c \$ | awk -F : '{a+=$2} END {print a/1024**2}'
    28.4284
    rg -c \$ 2.12s user 2.19s system 276% cpu 1.564 total
    awk -F : '{a+=$2} END {print a/1024**2}' 0.58s user 0.45s system 66% cpu 1.564 total

כאן הוא מוגבל ל גקבצים (אותו עץ לינוקס):

    % time pffxg.sh --workers 8 --cc --cmd wc -- -l | awk '$2 == "total" {a+=$1} END {print a/1024**2}'
    25.3935
    pffxg.sh --workers 8 --cc --cmd wc -- -l 0.76s user 0.54s system 734% cpu 0.177 total
    awk '$2 == "total" {a+=$1} END {print a/1024**2}' 0.02s user 0.00s system 9% cpu 0.177 total

ואת ריפגרף גרסה:

    % time rg -tc -c \$ | awk -F : '{a+=$2} END {print a/1024**2}'
    25.3844
    rg -tc -c \$ 3.49s user 1.54s system 441% cpu 1.140 total
    awk -F : '{a+=$2} END {print a/1024**2}' 0.38s user 0.38s system 66% cpu 1.140 total

Real Application Performance מגיע מאיזון, גמישות וטכניקות תכנות פונקציונליות; זה לא בא מקיבוע על טקטיקות מיקרו-אופטימיזציה הכרחיות בשפות תכנות סטטיות, מהודרות שהן דוב לעבוד איתו מנקודת מבט של איזון וגמישות. שפות צפופות וצריכות כאלה הן מטרות נהדרות עבור תחומי בעיות ספציפיים מאוד, אך הן נוראיות לביצועי יישומים בכל המערכת.

pffxg.sh זה לא מוצר, וזה לא מכירות. זוהי דוגמה** כדי להמחיש את הנקודה שלי בצורה דרמטית מאוד. אם אתה מכיר את ההיסטוריה הארוכה של פתרונות מסוננים-רקורסיביים-grep על GitHub, כולם מבוססים על הרעיון כי הבעיה עם המקורי של אנדי לסטר פרל מימוש חשבוןהאם זה נכתב ב פרל. הבעיה האמיתית היחידה מנקודת מבט של ביצועים היא כי פרל הוא נכתב על ידי אנדי, שלא נראה שהיה לו שום כישרון למושגים של ביצועי מערכות (כמו לחקלאות החוצה). חיפוש עבודת מקביליות למטרת בנייה ג בינארי), אבל במקום זאת מכוון לניידות עצלה על ידי ניסיון ללכוד את כל הקוד כטהור בעל הליך משנה יחיד פרל מוזרות.

מי ייתן ואלף פרחים יפרחו, לא משנה כמה טיפשים הם ייראו.