היי ,
למי שלא מבין על מה מדובר ... מצורף קישור לאשכול שכתבתי בו הודעה שקשורה לעניין .https://rotter.name/nor/prog/12368.shtml#17
תקראו אותה לפני שתמשיכו .
קראתם ? יפה .
הקוד לדוגמא שלי נמצא במשרד , אבל בכל מקרה , אני מצרף קוד מה - MSDN (שממנו לקחתי את הרעיון לפתירת הבעיה) , שמסביר לא פחות טוב את הדוגמא . (הקוד שלי שונה מפני שהייתי צריך לבצע התאמות מסויימות , מכיוון שהמחרוזות שלי באורך שונה והפונקציה לא נותנת מענה מספק , ויש לי כל מיני הגבלות על Allocate מראש , בקיצור , לא משנה)
שוב , אני נותן דוגמא לביצועים עם סינטקס רגיל , לעומת שימוש בפונקציה חדשה שמקצה זיכרון מראש .
קודם התוצאות , ואם מעניין אותכם , הקוד בסוף ההודעה .
Using standard concatenation 1000 concatenations took 16 ticks 2000 concatenations took 62 ticks 3000 concatenations took 157 ticks 4000 concatenations took 234 ticks 5000 concatenations took 453 ticks 10000 concatenations took 3219 ticksUsing pre-allocated storage 1000 Good-concatenations took 0 ticks 2000 Good-concatenations took 0 ticks 3000 Good-concatenations took 15 ticks 4000 Good-concatenations took 0 ticks 5000 Good-concatenations took 16 ticks 10000 Good-concatenations took 16 ticks 20000 Good-concatenations took 31 ticks 50000 Good-concatenations took 156 ticks 100000 Good-concatenations took 562 ticks
|
שימו לב להבדלים !
בשיטה הראשונה לוקח לי חצי שניה לשרשר 5000 מחרוזות , ובעזרת הפונקציה החדשה אני יכול לשרשר 100000 (!!!) מחרוזות באותו הזמן !
שימו לב , יש דוגמאות הרבה יותר קיצוניות , ככל שמעלים את כמות השרשורים בדרך הישנה , מדד הזמן עולה באופן לא ישיר !
ז"א שאם לוקח לי חצי שניה לשרשר 5000 מחרוזות , זה לא אומר שיקח לי שניה שלמה לשרשר 10000 מחרוזות . (אלא 3.5 שניות ...)
דוגמא יותר קיצונית :
בשביל לשרשר 20000 מחרוזות בשיטה הישנה , הפעולה תקח 29781 מילישניות (כמעט 30 שניות !!)
ולעומת זאת , שרשור 20000 מחרוזות בעזרת הקצאה מראש (הפונקציה החדשה) תקח 31 אלפיות השניה ! זמן זניח למדידה !
כדאי מאוד שלא תנסו מעל 20000 שרשורים בדרך הישנה , מפני שזה יגיע לרמה של דקות ולא שניות (למשל 30000 רשומות יקחו לכם בערך דקה וחצי ...).
בקיצור , הראיתי פה נגיעה קטנה בשיפורים שניתן לעשות לאפליקציות , במיוחד אם הם גדולות ומבצעות פעולות עיבוד רציניות .
כדאי לשים לב למה שכותבים ... לא משנה באיזו שפה אתם כותבים .
תמיד אפשר לשפר .
הקוד :
Option Explicit Const ConcatStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" Const ccIncrement = 50000 Private Declare Function GetTickCount Lib "KERNEL32" () As Long Dim ccOffset As Long Sub StdConcat(ByVal LoopCount As Long) Dim BigStr As String, I As Long, StartTick As Long StartTick = GetTickCount() For I = 1 To LoopCount BigStr = BigStr & ConcatStr Next I Debug.Print LoopCount; "concatenations took"; Debug.Print GetTickCount() - StartTick; "ticks" End Sub Sub Test_Concat() Debug.Print "Using standard concatenation" StdConcat 1000 StdConcat 2000 StdConcat 3000 StdConcat 4000 StdConcat 5000 StdConcat 10000 StdConcat 10000 Debug.Print Debug.Print "Using pre-allocated storage" MidConcat 1000 MidConcat 2000 MidConcat 3000 MidConcat 4000 MidConcat 5000 MidConcat 10000 MidConcat 20000 MidConcat 50000 MidConcat 100000 End Sub Sub Concat(Dest As String, Source As String) Dim L As Long L = Len(Source) If (ccOffset + L) >= Len(Dest) Then If L > ccIncrement Then Dest = Dest & Space$(L) Else Dest = Dest & Space$(ccIncrement) End If End If Mid$(Dest, ccOffset + 1, L) = Source ccOffset = ccOffset + L End Sub Sub MidConcat(ByVal LoopCount As Long) Dim BigStr As String, I As Long, StartTick As Long StartTick = GetTickCount() ccOffset = 0 For I = 1 To LoopCount Concat BigStr, ConcatStr Next I BigStr = Left$(BigStr, ccOffset) Debug.Print LoopCount; "pseudo-concatenations took"; Debug.Print GetTickCount() - StartTick; "ticks" End Sub
|
תהנו ...
