מאחורי המסך

משה למפרט, על תכנות מתקדם וביצועים ב-Web.

על הבלוג

עוד חדשות

אתרים שיש לי בהם יד ורגל

Internet Explorer 9 – חוויה ראשונית

היום ביליתי זמן ארוך בבחינת דפדפן העתיד של מיקרוסופט, IE9 בגירסת ה-Platform Preview שלו כפי שניתן להוריד מהרשת. כמובן שמדובר בגירסא בה הכל יכול להשתנות – ובכל זאת, הפצת הגירסא מראה על נכונות של מיקרוסופט להתקרב למפתחים שלה, וגם לגולשי הדפדפן שלה, שהוא עדיין הפופולארי ביותר בעולם, עם נתח שוק של כ-88% בישראל.

 

image

דף הבית של ערוץ 7 בדפדפן החדש.

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

 

הדבר הראשון שרציתי לבדוק זה ביצועים של רכיבים באתר, למשל הדוא"ל והפורומים של ערוץ 7. עשיתי את זה במצב IE9.
בתחושה (ללא מדידה מקצועית) – דפים במצב IE9 עולים משמעותית מהר יותר מאשר ב-IE8 קודמו. לעומת זאת – פעולות המבוצעות ב-JS דווקא איטיות יותר, ובצורה מורגשת בהחלט. גם אנימציות של  JQuery זוחלות.

כניסה ל-Devaloper Tools הראתה כי הרכיב הזה איטי מאוד (לא הפתעה למשתמשי הכלי המקביל ב-IE8) וטעינה שלו לאחר דף כבד אורכת לעיתים עד חצי דקה.
שיטוט מעמיק יותר הראה טאב חדש, למעקב אחרי בקשות HTTP. מזכיר את טאב NET  של Firebug או גירסא בסיסית של Fiddler.

image

 

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

image

 

הטבלה עוד טעונה שיפור להגיע לקרסוליים של Fiddler או Firebug, אבל בסך הכל עושה עבודה מצויינת בהחלט. נתון שהיא מציגה והאחרים לא יודעים להציג – Gap, אורך הזמן בין השלמת הבקשה לבין סיום טעינת הדף. יעיל לפעמים לאיתור בעיות מחוץ ל-HTTP Request עצמו.

image

 

עד כאן לבינתיים. לי נשאר רק לחכות (כהרגלי) לגירסא העברית. כשזו תגיע – נכתוב עליה בעז"ה.

ביצועים ב-Web: צמצום מספר הבקשות ל-JS ול-CSS

התחלתי לבצע את הרעיון הזה כחלק מהמהלך שלי להוריד (עוד יותר) את מספר הבקשות לדף בערוץ 7, על מנת להאיץ את טעינתו של אתר החדשות הנ"ל. מפה לשם התחלתי לבנות Handler שמקבל רשימת קבצי JS וקבצי CSS, ובונה משהו כזה:

// js script
function () {}
// css
document.write("<style>body {font-family:arial}</style>");

זה עבד יפה, אבל לא היה מושלם (שבר הפניות יחסיות לקובץ ה-CSS שאותן תיקנתי בעזרת search/replace, והיה קצת מכוער – ופגע קצת בביצועים בצד לקוח).אז חיפשתי קצת בגוגל, ומצאתי פיתרון אחר, שמבוסס על הערות ועל דרך לגרום ל-JS להתעלם מה-CSS ולהפך, ולטענת כותבו – גם עובר ולידציה.

 

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

 

'ייצור script עם הפנייה מתאימה, על בסיס Hash Shared Function GetScriptsHTML(ByVal Scripts() As String, ByVal CSS() As String) As String     Dim sHash As String = GetFilesHash("scripts", Scripts)     If CSS.Length > 0 Then sHash = MailFuncs.MD5(System.Text.Encoding.UTF8.GetBytes(sHash & GetFilesHash("css", CSS)))     Return "<script src=""Combine.ashx?js=" & Join(Scripts, ",") & "&css=" & Join(CSS, ",") & "&h=" & Mid(sHash, 1, 10) & """></script>" End Function Private Shared Function GetFilesHash(ByVal Folder As String, ByVal Files() As String) As String     Dim aFiles As New StringBuilder     For i As Integer = 0 To Files.Length - 1 ' שימו לב לתת הפניה לספריה הנכונה         aFiles.Append(vbCrLf & vbCrLf & IO.File.ReadAllText( Folder & "/" & Files(i)))     Next     Return MD5(System.Text.Encoding.UTF8.GetBytes(aFiles.ToString)) End Function

Shared Function MD5(ByVal Bytes() As Byte) As String     Dim oMd5 As New System.Security.Cryptography.MD5CryptoServiceProvider()     Dim Bytes2() As Byte = oMd5.ComputeHash(Bytes)     Return System.Convert.ToBase64String(Bytes2) ', 0, Bytes2.Length)    'Bytes2) >End Function

 

הקוד הזה כמובן לא גמור ויש עוד מה לשפר, בשלב הבא צריך לשמור ב-Cache כלשהו את תוצאות ה-MD5 של הקבצים (זו פעולה קצת יקרה) ומן הסתם אפשר לייצר קוד קצת יותר יפה

MySQL SSMA – ייבוא טבלאות מ-MySQL ל-MSSQL

מוצר חדש שעלה בשקט בשקט ב-CTP, ומיועד למי שנמצא על קו התפר בין MySQL, פרוייקט הקוד הפתוח הפופולארי לבין SQL Server.

 

image

מדובר בתוכנה קטנטנה ששוקלת רק 11MB על הכונן הקשיח, ודורשת את ה-MySQL ODBC Client שניתן להורדה חינם מאתר MySQL. אותי מפליא מדוע הם לא בחרו פשוט להשתמש ב-Native Provider של MySQL לסביבת .NET Framework., אבל מילא. שיהיה.

הכלי עצמו, לאחר שהותקן בדקה או שתיים, דורש רשיון (הניתן חינם באתר Microsoft) בדומה לכלים דומים (SSMA של Access)  ולאחר שנפתח נראה כמעט זהה לכלי המקביל עבור Access, למעט האשף שעושה את החיים קצת פשוטים יותר. הכלי, אגב, תומך גם בשדרוג ל-SQL Azure שבענן אותו מיקרוסופט דוחפת בכל הכח.

תחילה ניצור פרוייקט חדש:

image

בשלב הבא נתחבר ל-MySQL המקור ול-SQL Server היעד וניתן לתוכנה לנתח את מבנה הנתונים במקור, וגם מציע הצעות לשינויים במקרים של אי תאימות.

כשמדובר בהמרת ה-Schema של הטבלאות הוא עושה עבודה טובה, וממיר היטב גם את האינדקסים המצורפים לטבלה ומסייע (לא בדקתי)להעביר גם את הטריגרים. כמו שאר הכלים מהסדרה הוא תומך בהמרה און ליין וגם ביצירת קובץ SQL.
בנוסף לכך הוא מציג דו"ח מאוד יפה על DB והבעיות הנובעות מהבדלים בין SQL Server ל-MySQL בתחום הטיפול בתאריכים ואחרים, וכותב בסוגריים הערכת זמן לטיפול בבעיה.


בשלב הבא ניסיתי להמיר דרכו מסד נתונים של 3GB עליו מבוססת אפליקציית Web, הוא טען שהצליח, אולם כשניסיתי להעביר את המידע הוא טען כי ההמרה נכשלה.
בדיקה ב-Management Studio לא הראתה שום זכר לטבלאות שהיו אמורות להיווצר. ייצוא ידני של ה-SQL  שהוא הציע ליצור והרצה ידנית ב-Management Studio עבר חלק.

הליך העתקת המידע מורכב מעט ודורש הכרות פנימית עם מבנה הנתונים ועם MySQL ו-SQL Server באופן כללי. עם זאת – מרגע שהכל הוגדר כשורה, למעט חריגים - אין בעיות או הפתעות מיוחדות (חוץ מתאריכי האפס). העתקת המידע מתבצעת בד"כ ב"פרוסות" של כ-10,000  רשומות בפעולה, בתלות בנפח ובגודל הטבלה והזיכרון בשרת המקור והיעד.

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

 image

המסך הראשי של התוכנה. בצ"מ נמחקו פרטי הטבלאות.

בעז"ה מתישהו – על MySQL בסביבת .NET: רגישויות, ביצועים ועוד ועוד. ואולי גם הדרך ההפוכה – המרה מטבלאות של SQL Server לאלו של MySQL.

Nginx – פרוקסי הפוך לביזור וקיצוץ עומסים מ-IIS

Nginx הוא שרת קטן שנכתב ללינוקס (אבל עובד גם על חלונות) ומיועד למטרה אחת ויחידה: Reverse Proxy מתוחכם. הוא יודע לשמור אצלו ב-Cache את הקבצים הסטטיים למינהם ומוריד את העומס ה זה מה-I/O של שרת האפליקציה*, והוא יודע גם לבזר את הבקשות בין השרתים השונים שלכם תוך שימוש ב-Sticky Sessions כדי לוודא שכל גולש משוייך ל-Session בשרת "שלו".

בדרך כלל אתרים שזקוקים לדבר כזה משתמשים כבר ב-CDN או פיתרון דומה, אבל למי שצריך לשפר ביצועים של אתר בגודל בינוני+, שהגולשים שלו מרוכזים במדינה אחת זה יכול להיות פיתרון מצויין (וגם זול).

Nginx

 

 

* אמנם גם ל-IIS יש Cache משלו, Kernel Caching, שבהחלט מוריד עומסים בשרת בצורה משמעותית, אבל הוא לא מתמודד עם קבצים שנגישים בתדירות נמוכה יותר, ובחלק מסביבות העבודה עלולים להיות חלק לא קטן מהעומס. בנוסף – הוא גם מתמודד בצורה טובה פחות עם Caching של רכיבים דינאמיים מאשר  Cache חיצוני המיועד בין השאר גם לזה.
יש גם ייתרון לא קטן לפעמים בהעברת עלות הדחיסה – gzip של הקבצים משרת האפליקציה לשרת אחר.

דחיסת JS ו-CSS בצד שרת עם YUI

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

גיליתי באקראי שיש גירסא של דוחס ה-JS וה-CSS של YUI לסביבת .NET בקוד פתוח. אפשר להשתמש בו באמצעים מגוונים או עם MSBuild (מה שנשמע לי מעניין יותר) במהלך בניית גירסת ייצור.

מעניין.

IE בישראל ירד מתחת ל-90%. IE6 ירד ל-24%

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

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

 

ומה אצלכם?

SQL: חלוקה לדפים ביעילות

English: SQL Server and MySQL optimization for paging large tables. skip the Hebrew explanations and look at the SQL. the first is slow, the second is better and the third's cost is 1% of the original.
The four is MySQL specific "limit" feture and the last using ROW_NUMBER() function introduction in SQL Server 2005.

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

ניקח למשל טבלה של 1,000,000 רשומות. נקרא לה  forum_messages, ונצרף עוד טבלה, של 100,000 רשומות, נקרא לה forum_topics

נמלא אותן בנתונים של פורום ממוצע, סה"כ בין 5000 ל-70,000 הודעות פר פורום וכ-20 הודעות לשרשור. נשים אינדקס על מספר השרשור ואינדקס נוסף על מספר הפורום (יש כמובן עוד פרמטרים רבים, אבל ננסה לפשט אותם):

SELECT * FROM forum_messages, forum_topics WHERE m_forum=50 and t_id=m_topic ORDER BY m_date desc

יחזיר (נניח) 20,000 רשומות.

אבל לנו מספיק רק 20, אז נעשה משהו כזה:

SELECT top 20 * FROM forum_messages, forum_topics WHERE m_forum=50 and t_id=m_topic ORDER BY m_date desc

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

 

אבל אפשר לחסוך עוד קצת:

SELECT m_id, m_title,t_id,t_status from (SELECT top 20 * FROM forum_topics ORDER BY t_id desc) as x, forum_messages WHERE t_id=m_topic

בשיטה הזו, המכונה "Join מאוחר", במקום לבצע שליפה על 1,000,000*100,000 ואז נצמצם אותה, נשלוף קודם מטבלה אחת 20 רשומות ורק אז נצרף מהטבלה השניה את שאר המידע. השליפה הזו תיקח כ-25% מהשליפה שלפניה (כ-1% מהשליפה המקורית). אינדקס מתאים למיון יאפשר גם לחסוך עוד כמה אחוזים על ידי ייעול גם השלב הזה של השליפה.

ב-MySQL אגב, העבודה שלנו פשוטה בהרבה. שם אפשר פשוט לבצע חלוקה לדפים עם LIMIT הפשוט והיעיל.

SELECT m_id, m_title,t_id,t_status from (SELECT  * FROM forum_topics ORDER BY t_id desc limit 20,40) as x, forum_messages WHERE t_id=m_topic ORDER BY m_date 

יחזיר לנו את העמוד השני של הפורום מטבלת forum_topics, ואז יצרף אליה את הטבלה הכבדה יותר עם ההודעות לפי הצורך. הנה דוגמא למימוש כזה עבור SQL Server וחבריו תוך שימוש בפונקציה Row_Number שממומשת החל מ-SQL Server 2005

SELECT * FROM   (SELECT top 40 ROW_NUMBER() OVER(ORDER BY t_id,m_id) AS rownum, 
  
       * FROM (SELECT top 20 * FROM forum_topics ORDER BY t_id desc) as x, forum_messages WHERE t_id=m_topic) AS t1
WHERE  rownum > 20 AND rownum <= 40

כשהרעיון הוא לשלוף את מספר הרשומות המינימלי האפשרי ואז לסנן אותו לפי rownum

 

אם יש צורך לדעת גם את מספר העמודים, בשביל זה הומצאה פונקציית count(*), שתעשה את העבודה בצורה נפלאה. את התוצאות שלה הייתי שומר באיזה Cache ומעדכן רק כשמשהו באמת משתנה.

XP Mode בלי תמיכה במעבד

על בסיס VirtualBox ועוד סקריפט או שניים.

 

נשמע מעניין למי שיש (כמוני) מעבדים שפשוט לא תומכים בוירטואליזציה, ומדהים כאלה כאלה נמכרים (גם High-End ו-Quad Core). מן הסתם זה איטי יותר אבל זה יעבוטד.

 

http://www.boot-land.net/forums/index.php?noref=1&showtopic=9986

רעיונות רעים נפוצים ב-Web

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

 

  1. שימוש ב-GridView לחלוקה לדפים של עשרות אלפי רשומות.
  2. חלוקה לדפים בצד שרת – ASP.net (כלומר שליפה של עשרות אלפי רשומות מה-DB כדי להציג עשרים).
  3. רכיבי IFrame מיותרים. IFrame הוא רכיב כבד מאוד, גם בהיבט צד הלקוח (הדפדפן, והמריחות של IE שהוא הגורם להן) וגם בהיבט צד השרת (בקשות מיותרות).
  4. בקשות AJAX מיד לאחר הטעינה (Request מיותר ויקר, ועוד דינאמי).
  5. שימוש ביותר מ-JS Framework אחת בצד לקוח (כבד גם בצד השרת וגם בצד הלקוח).
  6. תמונות גדולות וכבדות שמוקטנות ב-HTML.
  7. מאות רכיבים קטנטנים שמייצרים מאות בקשות.
  8. שימוש מוגזם (מאוד) בעוגיות, למשל שמירת הודעות בפורומים שנקראו וכו'.
  9. Flash Loaders – אתר מגביל את שטח הדיסק לבאנר, אז טוענים אותו משרת חיצוני. בזבוז כפול.
  10. קבצים סטטיים לגמרי עם ? ותאריך עדכני (יש דרכים מוצלחות יותר למנוע Caching)
  11. ViewState של עשרות קילו בתים.
  12. Timeout של 20 שניות ומעלה.

בכנס שארגן שלמה גולדברג לגולשי פורום .NET בתפוז, נוכחתי לדעת על מתכנתים באמת מוכשרים, שלא תמיד מודעים להשלכות של מה שהם עושים על הביצועים. משפט כמו "אפשר לשמור עוגיות עד 2K באקספלורר" אולי נכון, אבל חסר הבנה לגמרי לגבי המשמעויות של עוגיה בנפח 2K על חוויית הלקוח.

 

ובמה אתם נתקלתם?

JS: טריק לא מוכר לשיפור זמן התגובה של DOM: createDocumentFragment

נדמיין לעצמנו את הלולאה הבאה:

var arr=[……];
  
for(var i=0;i<arr.length;i++) {

var d=document.createElement("div");
d.innerHTML=arr[i].html;
document.getElementById("divonpage").appendChild(d);

}

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

בכל איטרציה של הלולאה, מחושב מחדש arr.length, אחר כך נוצר div חדש, מתווסף לו תוכן והוא נוסף לדף, מה שמרענן מחדש את התצוגה ואת הטבלאות הפנימיות של הדפדפן.

אני מציע את השינוי הבא, והסברים בהערות:

var arr=[……],len=arr.length; // שמירה של כמות המשתנים במערך
var frag = document.createDocumentFragment(); // עיין בקישור

for(var i=0;i<len;i++) {

var d=document.createElement("div")
d.innerHTML=arr[i].html
frag.appendChild(d) // שמירה "בצד" של מערך מוכן לשימוש

}

// ועכשיו נעדכן את התצוגה של הדפדפן רק פעם אחת
document.getElementById("divonpage").appendChild(frag);

זה נכון שבדפדפנים החדשים יותר יש אופטימיזציות לפתרון בעיות מהסוג הזה, מצד שני, לרוב המוחלט של הגולשים (לפחות בישראל) יש IE6/7 שלא מסתכלים אפילו לכיוון הזה, אז עדיין שווה לעבוד. עובד על כל הדפדפנים מ-IE6 ומעלה (לא בדקתי IE5 וכנופייתו).

PageSlow של גוגל – שימוש ראשוני

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

לקחתי לניסוי את המתחרה החדש (יחסית) שלו מבית גוגל, והרצתי על אתר הבית שלנו בעבדית. כמה נקודות שהוא מגלה ו-YSlow בינתיים לא:

  • בקשות DNS מבוזבזות – דומיינים מהם נטען רק רכיב אחד שאפשר לחסוך (כך גיליתי רכ.
  • מקטין תמונות ומציע הצעות קונקרטיות על כל התמונות במערכת – חוסך טעינה של תמונה תמונה לתוכנה גרפית.
    הצרה הצרורה – הוא מציג רשימה ארוכה של תמונות בהן ניתן לחסוך. תחזיקו חזק! 37 byets. היה יעיל יותר אם הוא היה מתעלם מהן.
    הקטנה ידנית של תמונות ב-YSlow (איטי ולעיתים לא עובד) נותנת קובץ מעט קטן יותר לעיתים. זניח.
  • PageSlow עוקב גם אחרי CSS וביצועים של Selectors בדפדפנים שונים. נחמד.
  • Remove Unused CSS – נשמע נחמד להסיר רכיבים לא שימושיים של CSS, אבל בפועל לא שימושי בעליל. הרעיון הוא לייצר קובץ CSS בודד ולשים אותו ב-Cache של הלקוח, גם אם הוא מכיל קצת רכיבי עיצוב של דפים פנימיים.
  • בסעיף Cookie Size הכלי מתעלם מהרכיב המייצר Cookie הכי ארוך והכי כבד במערכת שלנו – Google Analytics. שאר העוגיות הם סוג של SessionID קטנים וזניחים במונחים של תקשורת או רוחב פס.
    הרכיב האחרון אחראי ל-Cookie של לא פחות מאשר 100Bytes, תכפילו את זה בכמות הבקשות ותבינו שזה המון.
    התמונות שלנו יושבות על דומיין אחר זה נכון, ובכל זאת.
  • PageSlow מתעלם מנושא ה-CDN. העניין דווקא חיובי מכיוון שזה שינוי שמורכב יחסית לבצע, השינויים האחרים שהוא מציע פשוטים יותר ויעילים לא פחות.
  • PageSlow מוצא URL שונה לקבצים זהים. למשל Home.js ו-home.js. ברכיכי AJAX הוא לעיתים מטעה אבל שווה תשומת לב.

השאר פחות או יותר לא שונה בהרבה: GZIP, זמן פקיעה (Expire ו-Cache Control), צמצום (Minify) של קבצי טקסט.

ההמלצה שלי: תשתמשו בשתיהן. מן הסתם התחרות תעשה להן ולאתר שלכם רק טוב.

גירסאות IE בטאבים

למי שעדיין אוכל קש מאחיזת 30% של IE6 בדפדפנים הישראליים ונזקק מדי פעם לפיתוח על הדפדפן הזה או גרועים ממנו

IETester היא תוכנה שמיועדת להציג בטאבים גירסאות שונות של IE. ניסיתי והתלהבתי.

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

image

בצילום: חדשות ערוץ 7 ללא שקיפות PNG.

תוכנה דומה יש גם מבית Microsoft, עם קצת פחות  פיצ'רים

לוח שנה ותאריך עברי ב-.NET

מאז ומתמיד השתמשתי בתאריך עברי. השייכות שלו ללוח השנה שעל פיו אני חי (חגים וכו') בגיל צעיר היא מובנת מאליה, ובהמשך - דברים שנהיים הרבה יותר פשוטים כשעובדים לפי לוח שנה עברי, כמו שינויים בתפילה וברכת המזון.

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

HebrewCalendar

ב-.NET, החל מגירסא 1 קיימת המחלקה System.Globalization.HebrewCalendar, המספקת לוח שנה עברי בדומה ללוחות נוספים מרחבי העולם, הממומשים במחלקות היורשות מ-System.Globalization.Calendar.
לכל הלוחות יש שיטות משותפות, בסגנון ה-GetX, כמו למשל GetDayOfMonth, GetMonth וכו', וכולם עובדים עם DateTime הסטנדרטי של הסביבה.

המרת תאריכים מעברי ולועזי ולהיפך:

Dim d as new DateTime(13,11,1987, new HebrewCalendar() 

ב- d יהיה אובייקט DateTime סטנדרטי.

d.ToString() יתן לנו 13/11/87, שזה התאריך הלועזי הרלוונטי.
כמובן שבמקרה העברי צריך להתחשב גם בשקיעה שיכולה להזיז את התאריך העברי יום קדימה.

הצגת תאריך עברי

Public Shared jewishCulture As System.Globalization.CultureInfo = System.Globalization.CultureInfo.CreateSpecificCulture("he-IL")

Public Shared Function ShortDate(ByVal dDate As Date) As String
    jewishCulture.DateTimeFormat.Calendar = HebCal
    Return dDate.ToString("dd MMMM", jewishCulture) End Function


בדיוק כמו תאריך לועזי, רק עם לוח שנה מתאים ואחר. גם שאר האפשרויות של DateTime.ToString() תעבודנה פה

 

חישובי תאריך עברי

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

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

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

אולי הגיע הזמן להרים את הכפפה ולפתח מחלקה שתירש מהמקורית ותתקן את העיוותים שלה (הקוד שאני כתבתי אז היה טלאי), בינתיים – חשוב לדעת שאלו המגבלות וכיצד חיים איתם. חוץ מזה – מדובר בכלי מצויין שהשימושים שלו רבים ומגוונים

לוח השנה של ערוץ 7 – פותח לפני כשנתיים על בסיס המחלקה הזו ונוספות, וכולל יכולות מאוד מעניינות נוספות.

דפים כמעט סטטיים זוחלים. למה ?

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

אבל עדיין דף הבית שלו זחל, ואני נשאלתי – למה!

התחברתי לשרת שלו והרצתי DebugDiag, שאימת את ההשערה שלי. הסתבר כי הרבה מאוד בקשות שנתקעו למשך שניות אחדות, כלל לא הגיעו למנגנון של ASP ונתקעו הרבה קודם.

אז למה?

ל-ASP ול-ASP.net יש בתוך Application Pool בסך הכל 25 (ניתן לשינוי) Threadים בזמן נתון, כאשר כל אחד כזה מקבל דף, מעבד אותו ומשחרר. במידה ויש איטיות באתר ה-Threadים האלה מתמלאים מהר מאוד והבקשות הבאות פשוט מתפנות בהמתנה ל-Thread. בעצם, כאשר דף אחד או שניים זוחלים זו שיטה בטוחה לגרום לכל האתר לזחול ובהמשך להתקע.

הפיתרון לבעיה הספציפית ההיא היה הפיכת חלק מהדפים לדפים סטטיים לגמרי, html, שמתעדכנים דרך ממשק הניהול של האתר. הללו מסופקים ישירות על ידי IIS, ללא צורך בתיווכים מתיווכים שונים, ולכן מגיעים ישר ללקוחות. כפועל יוצא – הלחץ על ה-Threadים יורד במעט מה שמקל באופן כללי על העומס בשרת.

כצ'ופר, על הדרך, אנחנו מקבלים גם שיפור מאוד נחמד בביצועים, גם ברמת IIS וגם ברמת יתרונותיו של Cache.

פיתוח מהנה.

עוד באותו עניין:
איטיות בסביבת ייצור

צנזורה שאבד עליה הכלח

כידוע לכולכם, לפני דקות קצרצרות הותר לפרסום כי יעקב טייטל משבות רחל, עולה מארה"ב שנעלם מעל פני האדמה לפני כשבועיים נאשם על ידי השב"כ באי-אלו פשעים. בראשית השבוע שעבר נחטפה אשתו באלימות מצומת תפוח שבשומרון בדרך להפגנה ודיון בבית המשפט בפתח תקווה. כתבה בנושא הוסרה מאתר ערוץ 7 ו-"וואלה", אבל בגוגל אפשר היה בקלות למצוא את הכתבות המחוקות או מידע שפורסם ב-Twitter.

במהלך השבועות האחרונים, מנהלת הצנזורה מלחמה מטופשת וחסרת תועלת להסרת פרסומים. כך למשל, הם היו מתקשרים מדי 23:00-24:00 בלילה, כדי לדרוש למחוק מהפורומים של ערוץ 7 את השרשורים שעסקו בנידון ופורסמו לאורך היום. הכל נכתב ופורסם, אבל הצנזורה הטפשית חשבה שבאמת אפשר להסתיר משהו.

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

אז עכשיו זה הותר לפרסום. נו שויין.

 

More Posts Next page »