האם שפת סי עדיין רלוונטית?

הפרבולה1

Well-known member
ל-class בד”כ מוקצה זכרון על ה-Heap ואילו ל-struct בד”כ על ה-Stack.
צריך הסבר נוסף? מה אתה עושה ער בשעה כזאת? אין לך מחר בית ספר?
זה לא מדויק , גם אוביקט של class יכול להיות על המחסנית .

טענה אחת לגבי ה"כבדות" של CPP נובעת בין היתר משימוש ב constructors / distructors , כלומר שכל פעם שנוצר אוביקט ( על המחסנית או באמצעות new ) נקרא קוד התחול וכל פעם שמנקים אותו נקרא קוד ניקוי , אבל מצד שני אם עובדים רק ב C עדין מתבקש להריץ קוד התחול וניקוי לstruct , אז לא בטוח ש C יותר יעיל , ואפילו לדעתי CPP יותר קומפקטי מבחינת סינטקס וכנראה מבלי להפסיד יותר מידי בביצועים לגבי התחול וניקוי אוביקטים . ואם אין צורך בהתחול\ניקוי אפשר פשוט לא להגדיר constructors distructors .

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

עוד טענה לגבי ה"כבדות" של CPP זה שימוש בפונקציות וירוטאליות אבל אם עובדים ב C ומתבקש לקרוא לפונקציות שונות על פי תנאי(ים) מסוימים , אז יש לממש את זה לבד עם פקודת if ותוספת דגלים שלפיהם הקוד יחליט לאיזה פונקציה לקרוא , או יותר יעיל לממש זאת עם מצביעים לפונקציות, שזה בעצם המימוש הפנימי ב CPP , יוצא ש CPP מממשת את זה הכי יעיל.
 

vinney

Well-known member
זה לא מדויק , גם אוביקט של class יכול להיות על המחסנית .
התשובה שלו לא הייתה ״לא מדויקת״ אלא לא נכונה. אין שום הבדל בין שתי ההגדרות.

הקצאה מערימה או ממחסנית זאת החלטה של קומפיילר שלרוב (להוציא אופטימיזציות) מבוססת על הscope וlife cycle של המשתנה. הקצאות דינמיות ב++C תמיד מבוצעות מערימה, אבל זה נכון גם לC.

טענה אחת לגבי ה"כבדות" של CPP נובעת בין היתר משימוש ב constructors / distructors , כלומר שכל פעם שנוצר אוביקט ( על המחסנית או באמצעות new ) נקרא קוד התחול וכל פעם שמנקים אותו נקרא קוד ניקוי , אבל מצד שני אם עובדים רק ב C עדין מתבקש להריץ קוד התחול וניקוי לstruct , אז לא בטוח ש C יותר יעיל , ואפילו לדעתי CPP יותר קומפקטי מבחינת סינטקס וכנראה מבלי להפסיד יותר מידי בביצועים לגבי התחול וניקוי אוביקטים . ואם אין צורך בהתחול\ניקוי אפשר פשוט לא להגדיר constructors distructors .
כמו שכתבת, איתחול וניקוי אובייקטים צריך להתבצע גם בC, רק ששם זה מתבצע בצורה ידנית. מתכנת צריך לכתוב את החלק הזה בעצמו (להוציא callocים למיניהם). אין פה הבדל מבחינת זמן ריצה, ההבדל הוא מבחינת בטיחות וקריאות הקוד. בזה ++C עדיפה בהרבה. במקרים בהם ״לא צריך שום אתחול״, אז לא צריך שום אתחול, ואופטימיזציות של ++C ייצרו את הקוד באותה היעילות של C. אם מכוונים לזמן ריצה, אז הקומפיילר יכול לעשות את כל האתחולים וההקצאה תהיה ב0 זמן ריצה, או לחלופין כל האתחולים וההקצאות נעשים לפני שהתוכנית מתחילה לרוץ (זה מה שמקובל לעשות גם במערכות משובצות מחשב, וגם הרבה פעמים במערכות זמן אמת). פה השפה בכלל לא משנה כלום.

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

עוד טענה לגבי ה"כבדות" של CPP זה שימוש בפונקציות וירוטאליות אבל אם עובדים ב C ומתבקש לקרוא לפונקציות שונות על פי תנאי(ים) מסוימים , אז יש לממש את זה לבד עם פקודת if ותוספת דגלים שלפיהם הקוד יחליט לאיזה פונקציה לקרוא , או יותר יעיל לממש זאת עם מצביעים לפונקציות, שזה בעצם המימוש הפנימי ב CPP , יוצא ש CPP מממשת את זה הכי יעיל.
זאת הדוגמא שבראבו הביא. מימוש מקובל של וירטואליזציה הוא בעזרת vtable, דהיינו dereference נוסף בכל קריאה. זה לא משמעותי אלא אם במקרה מאוד ספציפי זה הופך להיות משמעותי, ואז פותרים את המקרה הספציפי. לדוגמא, אתה כתבת interface עם מימוש ספציפי של פונקציה יחסית מצומצמת שעושה משהו קטן. אז הקריאה לפונקציה והdereference הנוסף עולים בערך כמו הפונקציה עצמה בזמן ריצה. עכשיו שים את זה בלולאה שרצה הרבה, ותקבל קנס משמעותי על המימוש הזה. הפתרון פשוט: תממש בצורה אחרת. בC מימוש זהה היה עולה לך אפילו יותר.
 

user32

Well-known member
מנהל
לשאלתך פרבולה: אני יודע פחות או יותר אבל כאמור לא כתבתי בשפות אלה כמעט 18 שנה ולכן לא רוצה לזרוק סתם דברים באוויר. מה גם שכשאני כתבתי בשפות הללו זה היה שרתים (כן, פעם כתבו אפליקציות שרת בC++) ופחות התעסקנו בדקויות של זמני ריצה כפי שנהוג בRT למשל. וכשכבר כתבתי RT זה היה בפרוייקטים קטנים (POC למיניהם) ואכן בשפת C אבל גם שם לא התעמקתי בהבדלים בין השפות כך שאין לי תשובה אינטלגנטית חוץ מאשר להסתמך על מה שויני כתב.
 

vinney

Well-known member
אין שום הבדל במהירות ריצה בין C לבין CPP בהגדרת שפה. שתי השפות מקומפלות לשפת מכונה ישירות, ואין שום מכונה וירטואלית, או איסוף זכרון, או קימפול תוך כדי ביצוע, כמו שיש להרבה שפות מודרניות אחרות (#C, פייתון, Java, וכד׳).

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

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

יוזר32 כתב ״כן, פעם כתבו אפליקציות שרת בC++״. ולמה ״פעם״? גם היום. בחברה שלי (גדולה ומוכרת) כותבים שרתים בCPP. אני כותב שרתים בCPP.

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

בקיצור - הרבה בורות נגלית בשרשור הזה...
 

פולגאר

Well-known member
אין שום הבדל במהירות ריצה בין C לבין CPP בהגדרת שפה. שתי השפות מקומפלות לשפת מכונה ישירות, ואין שום מכונה וירטואלית, או איסוף זכרון, או קימפול תוך כדי ביצוע, כמו שיש להרבה שפות מודרניות אחרות (#C, פייתון, Java, וכד׳).

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

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

יוזר32 כתב ״כן, פעם כתבו אפליקציות שרת בC++״. ולמה ״פעם״? גם היום. בחברה שלי (גדולה ומוכרת) כותבים שרתים בCPP. אני כותב שרתים בCPP.

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

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

vinney

Well-known member
אכן, הרבה בורות שלך שאתה בכלל משווה בין RT למערכת משובצת מחשב.
הרבה מאוד יישומים של מערכת משובצת מחשב נעשיים באופליין.
חכמולוג קטן, מעלית זה RT ו/או מערכת משובצת מחשב?
הבנת הנקרא זה לא הצד החזק שלך.
 

user32

Well-known member
מנהל
למען הדיוק, אין הבדל בזמן הריצה גם לקוד שנכתב שג'אווה, סי שארפ או פיתון וזו טעות נפוצה לחשוב שהן "איטיות". הקוד מקומפל לשפת מכונה ולמכונה לא אכפת מאיזו שפת תכנות הקוד הגיע. למי שמפריע הזמן טעינה וקומפילציה בזמן ריצה יכול להריץ קומפיילר מראש, משהו שנתמך ברוב השפות שציינתי אם לא בכולן.
בקורסי ג'אווה נהגו להציג קטעי קוד שרצים מהר יותר בג'אווה מאשר בC. הטריק היה האופטימייזר של JVM שהיה משמיט בלוקים שלמים של קוד שזיהה שלא אמורים להתבצע.
 

user32

Well-known member
מנהל
ולגבי שרתים: התכוונתי לאפליקציות צד שרת או לשרתי סוקט שמשתמשים בספריות IO מוכנות (סוקט...) ואינם אפליקציות זמן אמת. רוב תכנות הסרבר סייד הוא כזה.
 

vinney

Well-known member
שאלתי אותך לפחות 3 שאלות שציפיתי לתשובתך עליהן. אז אני אמתין עד שתענה לפני שאגלה לך באיזו שורה אני יושב בפסטיגל.
 

BravoMan

Active member
אני עוד זוכר כתיבת קוד עם MFC בVisal Studio, סיוט לא קטן. יעיל זה לא.
אתה מודע לכך ש-MFC היה ניסיון של MS לקחת API בנוי ל-C ולהפוך אותו ל-OO לשם תמיכה ב-CPP?
זו בדיוק הסיבה שזה היה זוועתי - ניסו לדחוף CPP היכן שלא צריך.
 

vinney

Well-known member
אתה מודע לכך ש-MFC היה ניסיון של MS לקחת API בנוי ל-C ולהפוך אותו ל-OO לשם תמיכה ב-CPP?
זו בדיוק הסיבה שזה היה זוועתי - ניסו לדחוף CPP היכן שלא צריך.
כן. זה היה זוועתי מהרבה סיבות, אבל לא כי ״ניסו לדחוף CPP היכן שלא צריך״. אני התחלתי לתכנת בחלונות עם הספר הזה (שגם במקרה היה הדבר הראשון שקניתי באמאזון עוד לפני שבארץ בכלל שמעו על אמאזון, בדואר היו נורא מופתעים מהחבילה שקיבלתי). המעבר שלי מWinAPI לMFC אחרי זה היה די חלק, וזה בעיקר כי לא ממש הרגשתי שום תרומה של ++C בMFC, השימוש במחלקות היה בעיקר כדי לייצר מעטפת לקוד C.

מייקרוסופט מאז השתפרו בהרבה, ועכשיו רוב העבודה על חלונות נעשית על #C בכלל, כולה OOP מא׳ עד ת׳, ואף אחד לא כותב בC. אבל אי שם בשנות ה90 - C הייתה מלכה גם לתכנות חלונות. כל הVBים ו.NETים הגיעו הרבה אחרי.
 

BravoMan

Active member
כן. זה היה זוועתי מהרבה סיבות, אבל לא כי ״ניסו לדחוף CPP היכן שלא צריך״. אני התחלתי לתכנת בחלונות עם הספר הזה (שגם במקרה היה הדבר הראשון שקניתי באמאזון עוד לפני שבארץ בכלל שמעו על אמאזון, בדואר היו נורא מופתעים מהחבילה שקיבלתי). המעבר שלי מWinAPI לMFC אחרי זה היה די חלק, וזה בעיקר כי לא ממש הרגשתי שום תרומה של ++C בMFC, השימוש במחלקות היה בעיקר כדי לייצר מעטפת לקוד C.

מייקרוסופט מאז השתפרו בהרבה, ועכשיו רוב העבודה על חלונות נעשית על #C בכלל, כולה OOP מא׳ עד ת׳, ואף אחד לא כותב בC. אבל אי שם בשנות ה90 - C הייתה מלכה גם לתכנות חלונות. כל הVBים ו.NETים הגיעו הרבה אחרי.
טוב, אם בנוסטלגיה עסקינן, זה היה הספר שהכניס אותי לפיתוח Windows משמעותי:

לפני זה איכשהו הצלחתי לקשקש דברים ב-VB (לא גרסת NET.).

אכן MS דחפו #C חזק (תודות ל-Java), אבל היום הם בעצמם כותבים יישומים ל-Desktop בשפות אחרות:

מצחיק - למרות שאני בד"כ עושה כמיטב יכולתי להתרחק מהמוצרים של החברה הזו (לפחות מוצרי תוכנה שלהם), דווקא מצאתי ש-VS code הוא עורך מצוין לפרויקטים קטנים ב-Python ו-go.

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

1. סוג האובסטרקציות שמשתמשים בהן - OOP, ניהול זיכרון אוטומטי, weak typing וכו'.
2. צורת הריצה של הקוד - VM, JIT, קומפילציה מראש ל-native.
3. תכנון הקוד עצמו ע"י המפתח.

האם עד כאן תסכים איתי?
 

vinney

Well-known member
מצחיק - למרות שאני בד"כ עושה כמיטב יכולתי להתרחק מהמוצרים של החברה הזו (לפחות מוצרי תוכנה שלהם), דווקא מצאתי ש-VS code הוא עורך מצוין לפרויקטים קטנים ב-Python ו-go.
לא נגעתי בVS כבר שנים (לפחות עשור), אז אני לא יכול להגיד משהו משמעותי על המוצר הנוכחי. הVisual Studio בזמנו היה מוצר מעולה ואחד הIDEים היותר טובים שהשתמשתי בהם בעיניי. גם עכשיו אני שומע מאחרים שVSCode זה מוצר מעולה, וזה נראה שגם לך יש את הרושם הזה. אני צריך לנסות את זה פעם באיזו הזדמנות.

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

1. סוג האובסטרקציות שמשתמשים בהן - OOP, ניהול זיכרון אוטומטי, weak typing וכו'.
אני לא חושב שלאלה יש השפעה מהותית בפני עצמם. בטח שלא לoop, אבל גם לא לניהול זכרון אוטומטי או typing. הכל תלוי ביכולתו של המתכנת להשתמש בכלים האלה בצורה טובה ויעילה, ואין שום הכרח שניהול זכרון אוטומטי או weak typing יפגעו בביצועים.
2. צורת הריצה של הקוד - VM, JIT, קומפילציה מראש ל-native.
אלה כנראה שכן ישפיעו על ביצועים, מן הסתם קומפילציה לnative מראש תביא לביצועים משופרים אל מול VM או JIT.

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

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

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

vinney

Well-known member
ניהול זיכרון אוטומטי בהחלט משפיע. ה-GC לא בא בחינם, הוא לוקח זמן ריצה, ולפעמים נכנס בדיוק בזמנים קריטיים.
ניהול זכרון אוטומטי זה לא בהכרח GC. ב++C יש ניהול זכרון אוטומטי (auto pointers), ואתה עדיין יודע בדיוק מתי כל אובייקט נוצר ומתי כל אובייקט נהרס (אלא אם אתה משתמש בshared pointers בצורה סופר גרועה, אבל נו שויין...)

כך גם weak typing משפיע, כי זה אומר שנכנסות המון בדיקות בזמן ריצה לוודא מה הטיפוס שיש שם כרגע ולהמיר אותו לטיפוס הנכון וכדומה.
לא, זה לא מה שזה אומר. זה אומר שאתה יכול להתעלם מהtyping בכתיבת קוד (או יותר נכון - תמיר type אחד באחר בקלות רבה בלי לשנות את מבנה הזכרון עצמו), זה לא בהכרח אומר שהבדיקות הן בזמן ריצה או שבכלל יש בדיקות. ב++C כמו שאמרתי נדיר מאוד שמתמשתים בבדיקות בזמן ריצה (RTTI), למעשה אף פעם לא נתקלתי בזה בתעשיה.

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

בהחלט יש לבחירת השפה ואופן הקומפילציה מה להשפיע על המהירות והיעילות, אבל זה לא חד משמעי לכאן או לכאן
זה בדיוק מה שאמרתי.
 
ניהול זכרון אוטומטי זה לא בהכרח GC. ב++C יש ניהול זכרון אוטומטי (auto pointers), ואתה עדיין יודע בדיוק מתי כל אובייקט נוצר ומתי כל אובייקט נהרס (אלא אם אתה משתמש בshared pointers בצורה סופר גרועה, אבל נו שויין...)

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

לא, זה לא מה שזה אומר. זה אומר שאתה יכול להתעלם מהtyping בכתיבת קוד (או יותר נכון - תמיר type אחד באחר בקלות רבה בלי לשנות את מבנה הזכרון עצמו), זה לא בהכרח אומר שהבדיקות הן בזמן ריצה או שבכלל יש בדיקות. ב++C כמו שאמרתי נדיר מאוד שמתמשתים בבדיקות בזמן ריצה (RTTI), למעשה אף פעם לא נתקלתי בזה בתעשיה.
אולי אנחנו מדברים על שני דברים שונים. RTTI זה לא מה שאני מתכוון אליו כשאני אומר weak typing. ספ"פ היא strongly typed (יותר מ-C, אגב).
איך ממירים int ל-string (דבר שקורה על ימין ועל שמאל ב-JS אם לא נזהרים) בלי לשנות את מבנה הזיכרון עצמו?

נכון, אבל הJIT מבצע קוד בשביל לבצע את האופטימיזציות האלה. זה עדיין משהו שאתה יכול לכתוב ב++C, אם אתה רוצה, זה לא איזה קסם יש מאין.
כן, השאלה היא מה אתה יכול לכתוב בקלות ומה לא. לעשות אופטימיזציה כזו בספ"פ דורש לא מעט עבודה (לזהות בזמן ריצה שקיבלת את הערכים 4 ו-5 ולהריץ גרסה מאופטמת של הפונקציה) ולנפח מראש את הבינארי עם המון גרסאות כאלה, כשבשפות אחרות אתה מקבל את זה אוטומטית בלי להשקיע מאמץ מיוחד (אבל במחיר של שימוש ב-JIT, כמובן).

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

vinney

Well-known member
אולי אנחנו מדברים על שני דברים שונים. RTTI זה לא מה שאני מתכוון אליו כשאני אומר weak typing. ספ"פ היא strongly typed (יותר מ-C, אגב).
איך ממירים int ל-string (דבר שקורה על ימין ועל שמאל ב-JS אם לא נזהרים) בלי לשנות את מבנה הזיכרון עצמו?
יש type casting (שזה מה שעושים בC וCPP), ואין לזה לרוב שום השפעה על זמן ריצה או זכרון (חוץ מRTTI וdynamic_cast). ויש type conversion, שזה מה שJS עושה, וזה בוודאי עולה גם עולה. שניהם סממנים של weak typing.

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

כן, השאלה היא מה אתה יכול לכתוב בקלות ומה לא. לעשות אופטימיזציה כזו בספ"פ דורש לא מעט עבודה (לזהות בזמן ריצה שקיבלת את הערכים 4 ו-5 ולהריץ גרסה מאופטמת של הפונקציה) ולנפח מראש את הבינארי עם המון גרסאות כאלה, כשבשפות אחרות אתה מקבל את זה אוטומטית בלי להשקיע מאמץ מיוחד (אבל במחיר של שימוש ב-JIT, כמובן).
וודאי. כמו שאמרתי - צריך להכיר את הכלים ולהבין איך הם עובדים כדי לדעת מה הtrade offs שלך. אתה ממיר זמן ריצה בזמן פיתוח, בנפח קוד, בקריאות, בנפח זכרון, וכו׳ וכד׳. הכל בסוף מתורגם לאסמבלי, אבל אף אחד לא באמת כותב באסמבלר יותר (להוציא מקרי אופטימיזציה קיצוניים ביותר), יש סיבה לזה.


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

user32

Well-known member
מנהל
טוב, אם בנוסטלגיה עסקינן, זה היה הספר שהכניס אותי לפיתוח Windows משמעותי:

לפני זה איכשהו הצלחתי לקשקש דברים ב-VB (לא גרסת NET.).

אכן MS דחפו #C חזק (תודות ל-Java), אבל היום הם בעצמם כותבים יישומים ל-Desktop בשפות אחרות:

מצחיק - למרות שאני בד"כ עושה כמיטב יכולתי להתרחק מהמוצרים של החברה הזו (לפחות מוצרי תוכנה שלהם), דווקא מצאתי ש-VS code הוא עורך מצוין לפרויקטים קטנים ב-Python ו-go.

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

1. סוג האובסטרקציות שמשתמשים בהן - OOP, ניהול זיכרון אוטומטי, weak typing וכו'.
2. צורת הריצה של הקוד - VM, JIT, קומפילציה מראש ל-native.
3. תכנון הקוד עצמו ע"י המפתח.

האם עד כאן תסכים איתי?
אם כבר נוסטלגיה... אני התחלתי תכנות וונדוס בWIN16 ועוד לא היה אינטרנט בארץ כמעט לאף אחד כולל לי אז בטח שלא הזמנו ספרים מאמזון שעוד לא נוסדה אז. הטריק היה שמי שקנה קומפיילר חוקי של בורלנד למשל, קיבל user manuals: אחד לקומפיילר, אחד לWIN API ועוד אחד שאני לא זוכר, אולי מדריך התקנה או משהו כזה הכל בקופסה מהודרת. אה, והמסכי Help היו ממש מועילים, היה שם ממש הכל.
ואז בגיל 17 נסעתי לביקור מולדת בארה"ב ומיד נכנסתי לחנות ספרים גדולה לקנות ספרי תכנות שלא היו בארץ. לימים גיליתי שב"דיונון" החנות באוניברסיטת ת"א יש מבחר לא קטן של ספרות מקצועית שאין באף חנות אחרת בארץ.
אגב, לפני MFC בורלנד עשתה מעטפת דומה בשם OWL - Object Window Library שהיתה די מוצלחת ופופולרית ורק ב95 מיקרוסופט עקפה אותם והשתלטה על השוק.
לגבי הIDE: מסכים עם ברוו, עברתי לvscode לפני כמה שנים מאחר ולא רציתי לשלם על IDE לnode והוא מאוד מוצלח בעיניי. גם VS 6 היה אחלה מוצר בזמנו, הם יודעים את העבודה. אחרי הכל יש להם ניסיון מצטבר של 30 שנה.
אני דווקא חושב שOOP וירושה מתאים מאוד לUI וספריות קומפוננטות. זה מתחבר לחשיבה באופן אינטואיטיבי.
 
נערך לאחרונה ב:

הפרבולה1

Well-known member
אני דווקא חושב שOOP וירושה מתאים מאוד לUI וספריות קומפוננטות. זה מתחבר לחשיבה באופן אינטואיטיבי.
נכון, מתבקש שיהיה איזה מחלקת אב ראשית שמוגדרות בה ( כפונקציות וירטואליות ) כל הפונקציות הבסיסיות של האלמנטים הויזואליים ( הצגה, הסתרה, רענון, הזזה, שינוי גודל ...), וכל "הצאצאים" מממשים את אותם פונקציות הבסיסות בהתאם .
 
למעלה