| Mirage Source http://www.miragesource.net/forums/ |
|
| Using With http://www.miragesource.net/forums/viewtopic.php?f=201&t=3546 |
Page 1 of 1 |
| Author: | seraphelic [ Thu Apr 03, 2008 2:45 am ] |
| Post subject: | Using With |
My teach told me in VB, With's inside of With's are slow. When I added With's to the LoadPlayer sub, my Log In is instantaneous: From: Code: Sub LoadPlayer(ByVal index As Long, ByVal Name As String) Dim FileName As String Dim i As Long Dim n As Long Dim nFileNum As Integer FileName = App.Path & "\Accounts\" & Trim(Name) & ".bin" nFileNum = FreeFile Open FileName For Binary As #nFileNum Get #nFileNum, , Player(index).Login Get #nFileNum, , Player(index).Password For i = 1 To MAX_CHARS 'General Information Get #nFileNum, , Player(index).Char(i).Name Get #nFileNum, , Player(index).Char(i).Class Get #nFileNum, , Player(index).Char(i).Sex Get #nFileNum, , Player(index).Char(i).Sprite Get #nFileNum, , Player(index).Char(i).Level Get #nFileNum, , Player(index).Char(i).Exp Get #nFileNum, , Player(index).Char(i).Access Get #nFileNum, , Player(index).Char(i).PK Get #nFileNum, , Player(index).Char(i).Guild 'Vitals Get #nFileNum, , Player(index).Char(i).HP Get #nFileNum, , Player(index).Char(i).MP Get #nFileNum, , Player(index).Char(i).SP 'Stats Get #nFileNum, , Player(index).Char(i).STR Get #nFileNum, , Player(index).Char(i).DEF Get #nFileNum, , Player(index).Char(i).SPEED Get #nFileNum, , Player(index).Char(i).MAGI Get #nFileNum, , Player(index).Char(i).POINTS 'Worn Equipment Get #nFileNum, , Player(index).Char(i).ArmorSlot Get #nFileNum, , Player(index).Char(i).WeaponSlot Get #nFileNum, , Player(index).Char(i).HelmetSlot Get #nFileNum, , Player(index).Char(i).ShieldSlot ' Check to make sure that they aren't on map 0, if so reset'm If Player(index).Char(i).Map = 0 Then Player(index).Char(i).Map = START_MAP Player(index).Char(i).x = START_X Player(index).Char(i).y = START_Y End If ' Position Get #nFileNum, , Player(index).Char(i).Map Get #nFileNum, , Player(index).Char(i).x Get #nFileNum, , Player(index).Char(i).y Get #nFileNum, , Player(index).Char(i).Dir ' Inventory For n = 1 To MAX_INV Get #nFileNum, , Player(index).Char(i).Inv(n).Num Get #nFileNum, , Player(index).Char(i).Inv(n).Value Get #nFileNum, , Player(index).Char(i).Inv(n).Dur Next n ' Spells For n = 1 To MAX_PLAYER_SPELLS Get #nFileNum, , Player(index).Char(i).Spell(n) Next n Next i Close #nFileNum End Sub To: Code: Sub LoadPlayer(ByVal index As Long, ByVal Name As String) Dim FileName As String Dim i As Long Dim n As Long Dim nFileNum As Integer FileName = App.Path & "\Accounts\" & Trim(Name) & ".bin" nFileNum = FreeFile Open FileName For Binary As #nFileNum With Player(index) Get #nFileNum, , .Login Get #nFileNum, , .Password For i = 1 To MAX_CHARS With .Char(i) 'General Information Get #nFileNum, , .Name Get #nFileNum, , .Class Get #nFileNum, , .Sex Get #nFileNum, , .Sprite Get #nFileNum, , .Level Get #nFileNum, , .Exp Get #nFileNum, , .Access Get #nFileNum, , .PK Get #nFileNum, , .Guild 'Vitals Get #nFileNum, , .HP Get #nFileNum, , .MP Get #nFileNum, , .SP 'Stats Get #nFileNum, , .STR Get #nFileNum, , .DEF Get #nFileNum, , .SPEED Get #nFileNum, , .MAGI Get #nFileNum, , .POINTS 'Worn Equipment Get #nFileNum, , .ArmorSlot Get #nFileNum, , .WeaponSlot Get #nFileNum, , .HelmetSlot Get #nFileNum, , .ShieldSlot ' Check to make sure that they aren't on map 0, if so reset'm If .Map = 0 Then .Map = START_MAP .x = START_X .y = START_Y End If ' Position Get #nFileNum, , .Map Get #nFileNum, , .x Get #nFileNum, , .y Get #nFileNum, , .Dir ' Inventory For n = 1 To MAX_INV With .Inv(n) Get #nFileNum, , .Num Get #nFileNum, , .Value Get #nFileNum, , .Dur End With Next n ' Spells For n = 1 To MAX_PLAYER_SPELLS Get #nFileNum, , .Spell(n) Next n End With Next i End With Close #nFileNum End Sub So I'm lead to believe using With's are a huge optimization, anyone think differently or am I right? |
|
| Author: | Lea [ Thu Apr 03, 2008 4:13 am ] |
| Post subject: | Re: Using With |
With is merely a programmer convenience. It is optimized away at compile time. |
|
| Author: | Spodi [ Thu Apr 03, 2008 5:32 am ] |
| Post subject: | Re: Using With |
Dave wrote: With is merely a programmer convenience. It is optimized away at compile time. Actually it isn't. Not by a long shot. Its been a long time since I've looked into it, but I from what I remember, when you mark something with "With", the object gets stored in a local cache. With can also cause problems if you use it at times but End With is never reached (ie using Exit Sub). Compare the assembly for the following two codes: Code: Private Sub Form_Load() Call Test End Sub Public Sub Test() Form1.Caption = "Hello" End Sub and Code: Private Sub Form_Load() Call Test End Sub Public Sub Test() With Form1 .Caption = "Hello" End With End Sub Heres the assembly (all compilation optimization options ticked) Using with: Code: Private sub unknown_401A00 00401A00: push ebp 00401A01: mov ebp, esp 00401A03: sub esp, 0000000Ch 00401A06: push 004010A6h ; MSVBVM60.DLL.__vbaExceptHandler 00401A0B: mov eax, fs:[00h] 00401A11: push eax 00401A12: mov fs:[00000000h], esp 00401A19: sub esp, 00000010h 00401A1C: push ebx 00401A1D: push esi 00401A1E: push edi 00401A1F: mov var_0C, esp 00401A22: mov var_08, 00401090h 00401A29: xor edi, edi 00401A2B: mov var_04, edi 00401A2E: mov eax, [ebp+08h] 00401A31: push eax 00401A32: mov ecx, [eax] 00401A34: call [ecx+04h] 00401A37: mov eax, [402010h] 00401A3C: mov var_1C, edi 00401A3F: cmp eax, edi 00401A41: jnz 401A53h 00401A43: push 00402010h 00401A48: push 00401330h 00401A4D: call MSVBVM60.DLL.__vbaNew2 00401A53: mov edx, [00402010h] 00401A59: mov esi, [0040101Ch] 00401A5F: lea eax, var_1C 00401A62: push edx 00401A63: push eax 00401A64: call MSVBVM60.DLL.__vbaObjSetAddref 00401A66: mov eax, var_1C 00401A69: push 00401614h ; Hello 00401A6E: push eax 00401A6F: mov ecx, [eax] 00401A71: call [ecx+54h] 00401A74: cmp eax, edi 00401A76: fclex 00401A78: jnl 401A8Ch 00401A7A: mov edx, var_1C 00401A7D: push 00000054h 00401A7F: push 00401530h 00401A84: push edx 00401A85: push eax 00401A86: call MSVBVM60.DLL.__vbaHresultCheckObj 00401A8C: lea eax, var_1C 00401A8F: push edi 00401A90: push eax 00401A91: call MSVBVM60.DLL.__vbaObjSetAddref 00401A93: push 00401AA2h 00401A98: lea ecx, var_1C 00401A9B: call MSVBVM60.DLL.__vbaFreeObj 00401AA1: ret End Sub and no with: Code: Private sub unknown_4019C0 004019C0: push ebp 004019C1: mov ebp, esp 004019C3: sub esp, 0000000Ch 004019C6: push 00401096h ; MSVBVM60.DLL.__vbaExceptHandler 004019CB: mov eax, fs:[00h] 004019D1: push eax 004019D2: mov fs:[00000000h], esp 004019D9: sub esp, 00000010h 004019DC: push ebx 004019DD: push esi 004019DE: push edi 004019DF: mov var_0C, esp 004019E2: mov var_08, 00401088h 004019E9: mov var_04, 00000000h 004019F0: mov eax, [ebp+08h] 004019F3: push eax 004019F4: mov ecx, [eax] 004019F6: call [ecx+04h] 004019F9: mov eax, [402010h] 004019FE: test eax, eax 00401A00: jnz 401A12h 00401A02: push 00402010h 00401A07: push 00401314h 00401A0C: call MSVBVM60.DLL.__vbaNew2 00401A12: mov esi, [00402010h] 00401A18: push 004015F8h ; Hello 00401A1D: push esi 00401A1E: mov edx, [esi] 00401A20: call [edx+54h] 00401A23: test eax, eax 00401A25: fclex 00401A27: jnl 401A38h 00401A29: push 00000054h 00401A2B: push 00401514h 00401A30: push esi 00401A31: push eax 00401A32: call MSVBVM60.DLL.__vbaHresultCheckObj 00401A38: mov eax, [ebp+08h] 00401A3B: push eax 00401A3C: mov ecx, [eax] 00401A3E: call [ecx+08h] 00401A41: mov eax, var_04 00401A44: mov ecx, var_14 00401A47: pop edi 00401A48: pop esi 00401A49: mov fs:[00000000h], ecx 00401A50: pop ebx 00401A51: mov esp, ebp 00401A53: pop ebp 00401A54: retn 0004h End Sub As you can see, it is clearly different so With is not just a programmer's shortcut. It seems that a local object containing the 32-bit address is created storing the address of the item you used With on. Then, at End With, it is released. So given this, it is likely that performance will be worse in the case of where little branching is used or the object being With'd is used very few times. In your case, you're branching down to the 2nd level (Player(index).Char(i)) and using it many times. I would think that this would be a lot faster since instead of looking up Player(index).Char(i) on the heap every time, you're grabbing the address from the stack. But, with VB6, who knows... nothing makes sense when it comes to micro-optimizations in VB6. |
|
| Author: | Lea [ Thu Apr 03, 2008 12:03 pm ] |
| Post subject: | Re: Using With |
-shrugs- Learn something new every day - interesting |
|
| Author: | Robin [ Thu Apr 03, 2008 1:01 pm ] |
| Post subject: | Re: Using With |
Assembly is confusing ;-; |
|
| Page 1 of 1 | All times are UTC |
| Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |
|