C#: LINQ חולשות LINQ (באיזה דברים לא לסמוך על LINQ)
-
שוב שלום למנהל הפרוייקט.
מכיוון שכולנו עובדים עם LINQ כסומא בארובה, וכקופסה שחורה, וכתינוק המשחק בחרב פיפיות, וכהדיוט בחדר בקרה של הכור האיראני. שאי אנו יודעים מה הוא עושה מאחור קלעיו (חוץ מלולאות גסות שזאת הנחה שאינני רוצה להניח על מפתחי LINQ כי אם כן גם אני יכול לפתח LINQ לכל שפה ומאי רבותיה????) וע"כ (ובוודאי ב LINQ TO SQL או ב LINQ TO ENTITY שהקריאה היא למסד הנתונים אשר דורש יעילות וחיסכון יותר משאר העניינים) שהלינק מנסה להתנהג בחכמה ולייעל ביצועים, אולם דא עקא, פעמים שהלינק נתפס בקלקלתו, ועושה את התיחקור באופן גרוע יותר מכל בר בי תיכנות דחד יומא.
על כן כל היודע איזה דבר רע על לינק, כאשר מתנהג בדרך נלוזה בחדרי חדרים, ומראה פנים כאילו הוא שלם שבשלמים, מוזמן לכתוב אותו כאן במדריך קבל עם ועולם, ולהוקיע את הפונקציה נגד השמש, למען לא ישתמשו בה רבים וכן שלמים להרוס ביצועי תוכנה, ולהשיב חרון אף הלקוחות מהם.
פורסם במקור בפורום CODE613 ב13/07/2013 21:52 (+03:00)
-
ביצועים בLinq זו שאלה כבדת משקל.
בעצם לכאורה אנו שוב זונחים את שקלולי הביצועים לטובת נוחות.
אז דבר ראשון, זו החלטה נבונה ברוב המקרים.
דבר שני, ברוב המקרים Linq יעיל בבירור.האם אפשר לבחון/לשלוט על זה? לא לגמרי.
הגישה צריכה להיות מה ההינו עושים ללא לינק. הלינק אמור לעשות בדיוק אותו הדבר שהיינו עושים, אבל "במקומנו".
אם יש לנו מערך מספרים שלמים, ואנו רוצים רק את הזוגיים.
איך היינו עושים ללא לינק? יוצרים ליסט, עוברים בלולאה על המערך, ובהתקיים התנאי (איבר לחלק לשתיים שווה 0) מוסיפים לליסט.
זהו זה. אז לינק עושה את זה ממש ככה.לפעמים אפשר ממש לתהות ביכולתיו של הlinq.
לדוגמה יש לנו מערך מספרים שלמים, ואנו רוצים לקחת את כל הגדולים ממאה, ובצורה ממויינת.
איך היינו עושים ללא לינק?
[u:37lq31qk]הדרך הפשוטה:[/u:37lq31qk]
א. ממיינים ע"י Array.Sort.
ב. מתקדמים מהקצה התחתון בלולאה עד שמגיעים למאה, ומשמה מעתיקים את המערך.
[u:37lq31qk]או הרבה יותר טוב והרבה יותר נחות (מתאים לאנשי C++) [/u:37lq31qk]
למיין בעצמנו, ואז תוך כדי להשמיט איברים גדולים ממאה.אז ללינק יש שלוש אפשרויות:
א. להיות טיפש מוחלט וקודם להסיר ואח"כ למיין.
ב. למיין ולהישען על המיון כדי לסנן נמוכים (בלתי סביר שלינק עושה כך, כי הוא לא יכול לדעת שיש קשר בין קובע המיון למהות התנאי).
ג. להיות חכם ולממש לבד את המיון, ותוך כדי להסיר נמוכים.אז הנה דוגמא שלינק יכול להיות ממש יעיל כמו מתכנת טרחן מעולם הC++. או להיפך...
אני חושב שהוא אכן חכם ויעיל, אני לא יודע איך לבדוק זאת.
לקרוא IL לא כ"כ נעים לי, כלומר אני לא יודע...
ולראות ברפלקטור זה לא עוזר, כי הוא מציג שאילתת לינק...
בימים הקרובים אולי אכתוב מהו הרפלקטור הזה על הפתעות שהוא עשה לי לפעמים.פורסם במקור בפורום CODE613 ב18/07/2013 11:38 (+03:00)
-
אני לא יודע איך לבדוק זאת.
יש לי רעיון פשוט, תממש את שלושת האפשרויות, תפעיל טיימר שיקבע כמה זמן לקחה השאילתה.
אחר כך לממש את זה עם לינק ולהשוות ביצועים.
תעשה את זה על מיליון או עשר מיליון איברים, ותראה את ההפרשים בבירור.
מעניין אותי לדעת תוצאות.
תעדכן....פורסם במקור בפורום CODE613 ב18/07/2013 12:00 (+03:00)
-
אני לא יודע איך לבדוק זאת.
יש לי רעיון פשוט, תממש את שלושת האפשרויות, תפעיל טיימר שיקבע כמה זמן לקחה השאילתה.
אחר כך לממש את זה עם לינק ולהשוות ביצועים.
תעשה את זה על מיליון או עשר מיליון איברים, ותראה את ההפרשים בבירור.
מעניין אותי לדעת תוצאות.
תעדכן....בעבר בדקתי ככה. כל מיני שאלות שהיה לי.
אבל זה דרך מפותלת ומרגיזה.
תזכור שאם היה לי כח לכתוב כ"כ הרבה קוד, אז לינק היה מיותר בשבילי
יש כלים חינמיים לזה אבל לא הצלחתי כ"כ לעבוד איתם.פורסם במקור בפורום CODE613 ב18/07/2013 16:56 (+03:00)
-
הנה בדיקות כאלו בדיוק מהרשת:
לרעת לינק:
http://ox.no/posts/linq-vs-loop-a-performance-test
http://social.msdn.microsoft.com/Forums/en-US/facff412-118a-4a80-867a-66503463a638/measure-the-performance-of-a-linq-sort
http://martin.podval.eu/2010/10/c-sharp-linq-or-foreach-performance.html
http://www.alexyork.net/blog/2008/09/14/performance-of-foreach-loops-vs-linq/
http://www.codeproject.com/Articles/21934/LINQ-Performance-Test-My-First-Visual-Studio-2008http://www.dotnetscraps.com/dotnetscraps/post/linq-performance-part-1-linq-to-collection.aspxבלוג שמדבר הרבה על זה:
http://msmvps.com/blogs/jon_skeet/default.aspxיש הרבה כללים שנבנו מתצפיות איך כדאי לבנות את השאילתה, אבל אני חושב שהם לא כללי ברזל.
כי המסקנה היא מתצפיות, שיכולים להשתנות עקב שיפורים במנוע בכל גירסת דוט נט.אבל יש כללים הגיוניים.
לדוגמא לבדוק אם רשימה ריקה, עדיף לבדוק ע"י פונקציית Any שמחזירה לא במקרה ריק מאשר להשוות את Count לאפס.
זה ברור כשמש, בפרט כאשר התוצאה היא שיש איברים אבל אפי' במקרה שאין.
אולי נבנה רשימה של כאלה המלצות.פורסם במקור בפורום CODE613 ב18/07/2013 18:23 (+03:00)
-
בעיקרון LINQ מתחלק לכמה חלקים:
אם השאילתא פשוטה, כמו SELECT, הוא ממיר את השאילתא למחרוזת SQL, מריץ את זה בשרת, ומציף את הליסט בנתונים.
אם השאילתא יותר מורכבת, הוא "מנסה" להמיר אותה לפרוצדורה של SQL, מריץ אותה בשרת וכו'
ואם עשינו בשאילתא הפניות לפונקציות פנימיות אז:
[list:3fr0b55u][:3fr0b55u]אם הוא יכול להמיר גם את הפונקציה ההיא הוא ממיר אותה[/3fr0b55u]
[:3fr0b55u]אם הוא לא יכול, הוא קורה לכל הרשומות ומריץ את כל התהליך.[/3fr0b55u][/list:u:3fr0b55u]
איך אני יודע?
יש כלי מעקב על השרת שמראה את כל הבקשות שרצות.
בעז"ה אני ישתדל להראות כמה דוגמאות בקרוב.אגב אקסס עם ODBC מתנהל בערך באותה הדרך, ומכאן האיטיות שלו עם ODBC.
פורסם במקור בפורום CODE613 ב29/12/2013 21:18 (+02:00)
-
בעיקרון LINQ מתחלק לכמה חלקים:
אם השאילתא פשוטה, כמו SELECT, הוא ממיר את השאילתא למחרוזת SQL, מריץ את זה בשרת, ומציף את הליסט בנתונים.
אם השאילתא יותר מורכבת, הוא "מנסה" להמיר אותה לפרוצדורה של SQL, מריץ אותה בשרת וכו'
ואם עשינו בשאילתא הפניות לפונקציות פנימיות אז:
[list:uzb1e9br][:uzb1e9br]אם הוא יכול להמיר גם את הפונקציה ההיא הוא ממיר אותה[/uzb1e9br]
[:uzb1e9br]אם הוא לא יכול, הוא קורה לכל הרשומות ומריץ את כל התהליך.[/uzb1e9br][/list:u:uzb1e9br]
איך אני יודע?
יש כלי מעקב על השרת שמראה את כל הבקשות שרצות.
בעז"ה אני ישתדל להראות כמה דוגמאות בקרוב.אגב אקסס עם ODBC מתנהל בערך באותה הדרך, ומכאן האיטיות שלו עם ODBC.
שלום!
אתה מדבר על LinqToSql, אנחנו דיברנו על LINQ רגיל, ToObject.
אתה משתמש הרבה עם LinqToSql? שווה? אני מעולם לא ניסיתי.
מיקרוספט זנחו אותו לטובת Entity, ולEntity לא הצלחתי להתחבר, אז אני עובד עם ADO הרגיל.פורסם במקור בפורום CODE613 ב30/12/2013 10:28 (+02:00)
-
(ובוודאי ב LINQ TO SQL או ב LINQ TO ENTITY שהקריאה היא למסד הנתונים אשר דורש יעילות וחיסכון יותר משאר העניינים)
הבנתי מתוכן השאלה שמדובר גם על SQL.
אבל ברור שמול OBJECT עדיין יהיה עדיף להשתמש הזה למי ששוחה בSQL...LINQ זה משהו מטורף, ואני לא כ"כ בטוח שמייקרוסופט זנחו אותו כ"כ מהר...
לצערינו למייקרוסופט יש הסטורייה של פיתוח כמה טכנולוגיות במקביל, אולי מתוך תקווה שאחת מהם תתפוס. החשבון אומר שאם יש 10 טכנולוגיות בשוק, ו5 מתוכם שייכים למייקרוסופט, יש להם יותר מ50% סיכוי שישתמשו בטכנולוגיות שלהם. - למה יותר מ50%? כי מייקרוסופט זה נהיה אופנה (לצערינו...) - מה שלא היה בעבר. - מי שהיה בתחום לפני עשור ויותר זוכר שמייקרוסופט בתקופת גייסט לא העיזה לחלק מוצרים אפילו בגירסת נסיון. ופתאם, יש לנו את VS EXPRESS, גירסאות הדגמה לאופיס, מייקרוסופט משתפת פעולה עם הקוד הפתוח (האתר CodePlex שייך למייקרוסופט) , ועוד היד נטויה.... למה? אולי שינוי בתפיסה? אולי השלמה שככה השוק עובד? ואולי כדי להמשיך ולשלוט על השוק, בעיקר שוק השרתים, אבל לא רק....)
כדי להוציא מליבם של תועים, קוד פתוח זה אחד הדברים הקרובים לליבי, ובגיל 18 קימפלתי את לינוקס ג'נטו למי שמכיר. (אגב ג'נטו, זו אחת הדוגמאות המעניינות של מייקרוסופט. בשנת 2005 זיהו בחור מוכשר (דניאל רובינס = מייסד ג'נטו), ולקחו אותו לעבוד אצלם, למה? חלוקות הדעות יש אומרים כדי שלינוקס לא תצליח להתקדם יותר מדאי, ויש אומרים כדי "להכיר" למייקרוסופט את יתרונות הקוד הפתוח. ומקובלנו מבית אבא שיש ויש הלכה כיש.
פורסם במקור בפורום CODE613 ב30/12/2013 11:08 (+02:00)