הבלוג של ארתיום
בלוג על לינוקס, תוכנה חופשית, מוזיקה, סלסה, ומה לא!
מאמרים בנושא לינוקס.
כשהקצאות הזיכרון משנות
יש הרבה צווארי בקבוק ביישומי רשת. רבים מהם נובעים מארכיטקטורת היישום, קריאות מערכת הפעלה ועוד.
אבל בשלב מסוים יישום רשת יעיל מגיע לנקודה בה הקצאות זיכרון מתחילות להשפיע בצורה משמעותית, בפרט זה נוגע לכל הקשור לעבודה עם מחרוזות.
ב־C++ יש מחרוזת הטובה הישנה: std::string
. אבל יש לה מגבלה אחת: היא דורשת הקצאה
של חתיכת זיכרון. זה נכון לכל מחרוזות בכל השפות ובכל הכלים גם אם הם immutable ומשתמשות ב-reference counting - עדין יש צורך להקצות זיכרון לאותה החתיכה.
בואו ניקח לדוגמה יישום פשוט שמאתר מקום כלשהו בעץ המשתמש במפתחות std::string
המבוסס על std::map
. הוא מקבל כפרמטר מחרוזת כמו /foo/bar/124
ומחלץ ממנה
את המפתחות foo
ו־bar
כחלקים במסלול, יישום בסגנון xpath.
אז עבור פונקציה:
void find_path(std::string const &str);
הקריאה
find_path("/foo/bar/123");
תצטרך ליצור שלוש מחרוזות:
-
/foo/bar/123
foo
bar
כך או אחרת עבור שולש מחרוזות האלה נצטרך להקצות שלוש חתיכות זיכרון, גם אם המחרוזות שלנו משתמשות ב-reference counting או הן immutable.
אז כיצד CppCMS מתמודד עם הבעיה הזו:
קיימת מחלקה מיוחדת
cppcms::string_key
שמחזיקה מתוכה את ה־std::string
הישן והטוב. אבל בנוסף, ניתן ליצור את אותה המחלקה באופן מפורש מזוג מצביעים מטיפוס char const *, כך שהיא שומרת רק הצבעה לטקסט ולא מעתיקה אותו.כמובן, שבמקרה הזה, המשתמש הוא האחראי לכך שהמצביעים יישארו תקפים כל עוד משתמשים באובייקט הזה.
עכשיו נשנה את הפונקציה
find_path
קלות ונוסיף לה עוד גרסה:void find_path(char const *str); void find_path(std::string const &str);
עכשיו, נשתמש רק במחרוזות שלא "מחזיקות בעלות על התוכן" ובכך נוכל ליצור מחרוזת מקורית ותת־מחרוזות foo ו־bar בלי להקצות זיכרון בכלל.
כמובן, זה הקו הכללי, אבל יש עוד הרבה טריקים מעניינים נוספים שמאפשרים למנוע או להוריד את כמות ההקצאות זיכרון כמו שימוש ב־pool שמוקצה פעם אחת ומשוחרר בסוף בבת אחת, שימוש במחסנית עבור קטעים קטנים ועוד.
CppCMS החל מגרסה 0.99.9 ששוחררה היום, אימץ את הטכניקה הזו בצורה רחבה ואפשר, במקרים מסוימים, להכפיל את ביצועים המערכת כולה.
כמובן, כשמשתמשים בטריקים האלה צריך להיות זהיר במיוחד גבי ניהול זיכרון ידני. אלא אם, קטע קוד רץ הרבה פעמים או כבר זיהיתם קטע מסוים כצוואר בקבוק, תשתמשו במחרוזת הרגילה. בסופו של דבר, הקצאה של זיכרון היום זה תהליך יחסית מהיר, אם לא מנצלים אותו לרעה.
שוחררה גרסת Boost.Locale חדשה
אחרי עבודה ארוכה על שיפורי ממשק ותיקוני בעיות שהועלו בתהליך בחינה רשמית של Boost.Locale הגרסה החדשה 4.0.0 שוחררה.
בקרוב אתחיל לשלב אותה בעץ svn של Boost, כך שאם הכל ילך בסדר, אני צופה שהיא תיכנס לגרסה 1.48 או לכל המאוחר 1.49 של Boost.
כרגיל:
- הורדה:
http://sourceforge.net/projects/cppcms/files/cppcms/ - תיעוד ומדריכים:
http://cppcms.sourceforge.net/boost_locale/html/index.html
במקביל שוחררה גרסת CppCMS 0.99.8 שמכילה את כל השינויים של Boost.Locale וגם תיקוני באגים שהצטברו במהלך 3 חודשים אחרונים.
אם עדיין לא שמתם לב, אני נותן הרצאה על Boost.Locale באוגוסט פינגווין - תבואו יהיה מעניין (גם אם אתם לא מדברים ב־C++)
בניות ובדיקות ליליות ו־VirtualBox
כל מי שמפתח פרויקט מורכב שתומך במספר רב של פלטפורמות יודע עד כמה זה קשה להוציא גרסה בדוקה שתעבוד בכל אחת מהן.
נכון, כולנו ;)
כותבים טסטים אוטומטיים ודואגים שהם יעברו בשלום לפני שחרור הגרסה, אבל... זה לא תמיד מספיק כי תמיד משהו איפשהו נשבר ולפי חוק מרפי משהו יישבר דווקא במקודם שלא עשית בו בדיקה נוספת.
כנ"ל CppCMS, אפילו שיש לי מערכת Unit-Tests שלמה, מידי פעם יש פספוסים בשחרור גרסה. וזה ברור: כשאתה מנסה לתמוך ב־GCC החל מ־3.4 עד 4.5, בקומפיילר של MSVC ושל Intel ב־Solaris, Linux, BSD, Mac OS X ו־Windows אז משהו בתוך כ־40 אלף שורות קוד חייב להישבר.
אז כבר הרבה זמן אני מחזיק מספר מערכות הפעלה על VirtualBox כדי לבצע בדיקות מידי פעם, רק שהפעם, הבנתי שהגיע זמן למכן את התהליך. ובכן, יצרתי מערכת Build לילית שבונה גרסה נקייה מ־trunk ומריצה טסטים. זה יחסית פשוט כאשר מדובר במכונה מקומית, ויש אפילו מערכות מוכנות לזה, אבל כשצריך לשלב מספר מערכות פעלה וסביבות וירטואליות, זה כבר קצת יותר מסובך.
בכל מקרה, בניתי סקריפט, שרץ מתוך crontab ומעלה מכונה וירטואלי, מתחבר אליה דרך ssh מריץ תסריט בניה וטסט ואז מוריד אותה באופן אוטומטי וכך לכל למכונה (למעשה Solaris ו־FreeBSD).
כאשר ניסיתי לעשות את אותו הטריק עם XP הסיפור הפך להיות מתסכל, בשרת FreeSSHD פשוט לא הצלחתי לבצע password-less login על־אף מאמצים רבים וקריאת התיעוד. בכל מקרה, המוצר הזה השאיר לי תחושה של מוצר "חצי־אפוי" כי הוא לא תמיד התנהג כמו שהוא אמור.
אחר־כך ניסיתי copssh, גם הוא היה כישלון טוטלי מכיוון שלא הצליח להעלות סרביס של ssh עם הודעות שגיאה על הרשאות ומשתמש ב־Even Log. החיפושים ברשת לא הניבו תוצאות. אז עברתי לגישה אחרת.
העתקתי את התסריט וכל הקבצים הנדרשים לשרת Samba והכנתי תסריט bat שרץ בחלונות וניגש תיקיה עם עליית המערכת. אם הקובץ נמצא, הוא בונה גרסה ומריץ טסטים, לאחר מכן שם את התוצאות באותו שרת ה־samba. עקום, אבל איכשהו עובד (כמו כל דבר אחר בחלונות...)
וכך נולדה מערכת בניה ובדיקות ליליות של CppCMS שמבצעת בדיקה על מספר פלטפורמות ומייצרת דו"ח יומי. בדיוק בגלל הדברים האלה אתה מבין עד כמה וירטואליזציה היא דבר אדיר.
CppCMS מול Java/JSP, C#/Asp.Net, PHP
פרסמתי השוואת ביצועים עדכנית בין CppCMS ושלוש טכנולוגיות web מובילות: PHP, Asp.Net/Mono ו־Java/JSP.
התוצאות וההסברים פורסמו כאן: http://art-blog.no-ip.info/cppcms/blog/post/67
התקנת תמיכה ב־LaTeX בעברית בהפצה מודרנית
אחת הבעיות להתחיל לעבוד עם LaTeX בעברית זה להתקין את התמיכה בו. לכן, רשמתי רשימת הערות להתקנה של תמיכה בעברית בהצפה מודרנית.
שימו לב, תתקינו בבקשה הפצת texlive ולא tetex, ההפצות המודרניות כמו Debian ו־Ubuntu באות כבר עם texlive.
שלבים בקצרה:
- הסירו ivritex אם מותקן
- התקינו texlive אם לא מותקן
- התקינו culmus-latex-0.7
- התקינו biditex
בפירוט
אם חבילת ivritex מותקנת במחשב שלכם, הסירו אותה ותמחקו ספרית .texmf בספריית הבית שלכם (שימו לב ל־"." שבתחילת שם הספריה).
התקינו LaTeX אם הוא לא מותקן, וודאי כי אתם משתמשים בחבילת texlive. בגדול tetex גם עובד אבל צפו בעיות.
וודאו כי יש לכם פקודות mktexlsr ו־updmap-sys (ניתן לבדוק אם פקודת which). אם לא התקינו את החבילות המתאימות.
הורידו את הגרסה האחרונה של culmus-latex (נכון לעכשיו 0.7) מפרויקט ivritex. להורדה כאן.
שימו לב, אתם לא צריכים חבילת src אלא culmus-latex-XX.tar.gz שמכילה את את הגופנים המוכנים מראש. פרוס אותה והרץ
make install
בתור root או בעזרת sudo.
בדוק ש־LaTeX בעברית עובד ע"י הרצה קומפילציה של דוגמה בחבילת culmus-latex, בתיקיית examples בצורה הבאה:
latex culmus-ex.tex dvips culmus-ex.dvi ps2pdf culmus-ex.ps
ובדיקת קובץ pdf שנוצר (בדקו שרואים עברית), כמו כן כדאי לבדוק כי pdflatex עובד ע"י הרצת
pdflatex culmus-ex.tex