Author | Message | Time |
---|---|---|
BreW | [code] unsigned int GetIcon(unsigned long client, unsigned long flags) { unsigned int rettemp = 0; switch (client) { case CLIENT_CHAT: //0x43484154: rettemp++; case CLIENT_W3XP: //0x57335850: rettemp++; case CLIENT_WAR3: //0x57415233: rettemp++; case CLIENT_W2BN: //0x5732424E: rettemp++; case CLIENT_D2XP: //0x44325850: rettemp++; case CLIENT_D2DV: //0x44324456: rettemp++; case CLIENT_DSHR: //0x44534852: rettemp++; case CLIENT_DRTL: //0x4452544C: rettemp++; case CLIENT_JSTR: //0x4A535452: rettemp++; case CLIENT_SSHR: //0x53534852: rettemp++; case CLIENT_SEXP: //0x53455850: rettemp++; } if ((flags & 1) == 1) rettemp = 12; if ((flags & 2) == 2) rettemp = 13; if ((flags & 4) == 4) rettemp = 14; if ((flags & 8) == 8) rettemp = 15; if ((flags & 32) == 32) rettemp = 16; if ((flags & 64) == 64) rettemp = 17; return rettemp; } [/code] using MSVC6, compiles to: [code] 0040B540 55 PUSH EBP 0040B541 8BEC MOV EBP,ESP 0040B543 51 PUSH ECX 0040B544 51 PUSH ECX 0040B545 8365 FC 00 AND DWORD PTR SS:[EBP-4],0 0040B549 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 0040B54C 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX 0040B54F 817D F8 5254534A CMP DWORD PTR SS:[EBP-8],4A535452 0040B556 77 3C JA SHORT 0040B594 0040B558 817D F8 5254534A CMP DWORD PTR SS:[EBP-8],4A535452 0040B55F 0F84 96000000 JE 0040B5FB 0040B565 817D F8 54414843 CMP DWORD PTR SS:[EBP-8],43484154 0040B56C 74 55 JE SHORT 0040B5C3 0040B56E 817D F8 56443244 CMP DWORD PTR SS:[EBP-8],44324456 0040B575 74 6F JE SHORT 0040B5E6 0040B577 817D F8 50583244 CMP DWORD PTR SS:[EBP-8],44325850 0040B57E 74 5F JE SHORT 0040B5DF 0040B580 817D F8 4C545244 CMP DWORD PTR SS:[EBP-8],4452544C 0040B587 74 6B JE SHORT 0040B5F4 0040B589 817D F8 52485344 CMP DWORD PTR SS:[EBP-8],44534852 0040B590 74 5B JE SHORT 0040B5ED 0040B592 EB 7C JMP SHORT 0040B610 0040B594 817D F8 50584553 CMP DWORD PTR SS:[EBP-8],53455850 0040B59B 74 6C JE SHORT 0040B609 0040B59D 817D F8 52485353 CMP DWORD PTR SS:[EBP-8],53534852 0040B5A4 74 5C JE SHORT 0040B602 0040B5A6 817D F8 4E423257 CMP DWORD PTR SS:[EBP-8],5732424E 0040B5AD 74 29 JE SHORT 0040B5D8 0040B5AF 817D F8 50583357 CMP DWORD PTR SS:[EBP-8],57335850 0040B5B6 74 12 JE SHORT 0040B5CA 0040B5B8 817D F8 33524157 CMP DWORD PTR SS:[EBP-8],57415233 0040B5BF 74 10 JE SHORT 0040B5D1 0040B5C1 EB 4D JMP SHORT 0040B610 0040B5C3 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0040B5C6 40 INC EAX 0040B5C7 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 0040B5CA 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0040B5CD 40 INC EAX 0040B5CE 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 0040B5D1 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0040B5D4 40 INC EAX 0040B5D5 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 0040B5D8 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0040B5DB 40 INC EAX 0040B5DC 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 0040B5DF 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0040B5E2 40 INC EAX 0040B5E3 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 0040B5E6 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0040B5E9 40 INC EAX 0040B5EA 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 0040B5ED 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0040B5F0 40 INC EAX 0040B5F1 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 0040B5F4 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0040B5F7 40 INC EAX 0040B5F8 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 0040B5FB 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0040B5FE 40 INC EAX 0040B5FF 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 0040B602 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0040B605 40 INC EAX 0040B606 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 0040B609 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0040B60C 40 INC EAX 0040B60D 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 0040B610 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] 0040B613 83E0 01 AND EAX,1 0040B616 83F8 01 CMP EAX,1 0040B619 75 07 JNZ SHORT 0040B622 0040B61B C745 FC 0C000000 MOV DWORD PTR SS:[EBP-4],0C 0040B622 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] 0040B625 83E0 02 AND EAX,2 0040B628 83F8 02 CMP EAX,2 0040B62B 75 07 JNZ SHORT 0040B634 0040B62D C745 FC 0D000000 MOV DWORD PTR SS:[EBP-4],0D 0040B634 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] 0040B637 83E0 04 AND EAX,4 0040B63A 83F8 04 CMP EAX,4 0040B63D 75 07 JNZ SHORT 0040B646 0040B63F C745 FC 0E000000 MOV DWORD PTR SS:[EBP-4],0E 0040B646 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] 0040B649 83E0 08 AND EAX,8 0040B64C 83F8 08 CMP EAX,8 0040B64F 75 07 JNZ SHORT 0040B658 0040B651 C745 FC 0F000000 MOV DWORD PTR SS:[EBP-4],0F 0040B658 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] 0040B65B 83E0 20 AND EAX,20 0040B65E 83F8 20 CMP EAX,20 0040B661 75 07 JNZ SHORT 0040B66A 0040B663 C745 FC 10000000 MOV DWORD PTR SS:[EBP-4],10 0040B66A 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] 0040B66D 83E0 40 AND EAX,40 0040B670 83F8 40 CMP EAX,40 0040B673 75 07 JNZ SHORT 0040B67C 0040B675 C745 FC 11000000 MOV DWORD PTR SS:[EBP-4],11 0040B67C 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0040B67F C9 LEAVE 0040B680 C3 RETN [/code] In release mode too. With all optimizations turned on. [me=brew]throws up[/me] | December 27, 2007, 6:41 PM |
UserLoser | cool | December 27, 2007, 7:42 PM |
Myndfyr | Your code sucks. You should have the flags check before the switch block, since the flags make the switch totally irrelevant. Also, the fact that you're using fallthrough is probably what's preventing it from breaking it into one of the other optimizations. For this number of cases, I wouldn't have expected to see it use a jump table, but rather a divide-and-conquer strategy. But, since you're using fallthrough, divide-and-conquer wouldn't work (because, for instance, CLIENT_CHAT wouldn't get the right number of values. I bet the optimization (jump table or divide-and-conquer) would kick in if you just used constants with break statements. I was going to suggest that you might benefit from using a templated STL map (should be close to an O(1) lookup), but since I recalled that you don't like code reuse or software engineering beyond the 1940's, that may not be your desired route. | December 27, 2007, 9:21 PM |
Quarantine | Proof of brew's retardation | December 27, 2007, 9:45 PM |
warz | Just another bit of proof, among hundreds. | December 27, 2007, 10:12 PM |
BreW | [quote author=MyndFyre[vL] link=topic=17237.msg175522#msg175522 date=1198790517] You should have the flags check before the switch block, since the flags make the switch totally irrelevant. [/quote] that's true. I never really thought of that (or even looked at it until you mentioned that). Thanks. [quote] Also, the fact that you're using fallthrough is probably what's preventing it from breaking it into one of the other optimizations. For this number of cases, I wouldn't have expected to see it use a jump table, but rather a divide-and-conquer strategy. But, since you're using fallthrough, divide-and-conquer wouldn't work (because, for instance, CLIENT_CHAT wouldn't get the right number of values. I bet the optimization (jump table or divide-and-conquer) would kick in if you just used constants with break statements. [/quote] A switch statement with all those constants didn't look right to me at the time i guess. BUT THE POINT IS that it shouldn'tve placed two movs after every inc, I would've kept that value in eax, but do all the and calculations with ecx. saves a lot of shit. Now that I look at it after what you've said, i think i know what it's trying to do, but just fails hard at doing it. The compiler also does so much more retarded shit, for example executes LEA twice on the same thing like so: [code] 0040ABC4 8D85 04FAFFFF LEA EAX,DWORD PTR SS:[EBP-5FC] 0040ABCA 50 PUSH EAX 0040ABCB 8D85 04FAFFFF LEA EAX,DWORD PTR SS:[EBP-5FC] 0040ABD1 50 PUSH EAX 0040ABD2 E8 D60B0000 CALL 0040B7AD [/code] my precious 6 bytes of space. wasted. [quote] I was going to suggest that you might benefit from using a templated STL map (should be close to an O(1) lookup), but since I recalled that you don't like code reuse or software engineering beyond the 1940's, that may not be your desired route. [/quote] You're right. C[u]++[/u] isn't my thing. | December 27, 2007, 10:45 PM |
BreW | grr. okay, so i did what myndfyre suggested. now it looks like this: [code] unsigned int GetIcon(unsigned long client, unsigned long flags) { unsigned int rettemp; if (flags & 64) return 17; if (flags & 32) return 16; if (flags & 8) return 15; if (flags & 4) return 14; if (flags & 2) return 13; if (flags & 1) return 12; switch (client) { case CLIENT_CHAT: //0x43484154: return 11; case CLIENT_W3XP: //0x57335850: return 10; case CLIENT_WAR3: //0x57415233: return 9; case CLIENT_W2BN: //0x5732424E: return 8; case CLIENT_D2XP: //0x44325850: return 7; case CLIENT_D2DV: //0x44324456: return 6; case CLIENT_DSHR: //0x44534852: return 5; case CLIENT_DRTL: //0x4452544C: return 4; case CLIENT_JSTR: //0x4A535452: return 3; case CLIENT_SSHR: //0x53534852: return 2; case CLIENT_SEXP: //0x53455850: return 1; } } [/code] [code] 0040B390 55 PUSH EBP 0040B391 8BEC MOV EBP,ESP 0040B393 51 PUSH ECX 0040B394 51 PUSH ECX 0040B395 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] 0040B398 83E0 40 AND EAX,40 0040B39B 83F8 40 CMP EAX,40 0040B39E 75 08 JNZ SHORT 0040B3A8 0040B3A0 6A 11 PUSH 11 0040B3A2 58 POP EAX 0040B3A3 E9 17010000 JMP 0040B4BF 0040B3A8 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] 0040B3AB 83E0 20 AND EAX,20 0040B3AE 83F8 20 CMP EAX,20 0040B3B1 75 08 JNZ SHORT 0040B3BB 0040B3B3 6A 10 PUSH 10 0040B3B5 58 POP EAX 0040B3B6 E9 04010000 JMP 0040B4BF 0040B3BB 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] 0040B3BE 83E0 08 AND EAX,8 0040B3C1 83F8 08 CMP EAX,8 0040B3C4 75 08 JNZ SHORT 0040B3CE 0040B3C6 6A 0F PUSH 0F 0040B3C8 58 POP EAX 0040B3C9 E9 F1000000 JMP 0040B4BF 0040B3CE 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] 0040B3D1 83E0 04 AND EAX,4 0040B3D4 83F8 04 CMP EAX,4 0040B3D7 75 08 JNZ SHORT 0040B3E1 0040B3D9 6A 0E PUSH 0E 0040B3DB 58 POP EAX 0040B3DC E9 DE000000 JMP 0040B4BF 0040B3E1 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] 0040B3E4 83E0 02 AND EAX,2 0040B3E7 83F8 02 CMP EAX,2 0040B3EA 75 08 JNZ SHORT 0040B3F4 0040B3EC 6A 0D PUSH 0D 0040B3EE 58 POP EAX 0040B3EF E9 CB000000 JMP 0040B4BF 0040B3F4 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] 0040B3F7 83E0 01 AND EAX,1 0040B3FA 83F8 01 CMP EAX,1 0040B3FD 75 08 JNZ SHORT 0040B407 0040B3FF 6A 0C PUSH 0C 0040B401 58 POP EAX 0040B402 E9 B8000000 JMP 0040B4BF 0040B407 8365 FC 00 AND DWORD PTR SS:[EBP-4],0 0040B40B 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 0040B40E 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX 0040B411 817D F8 5254534A CMP DWORD PTR SS:[EBP-8],4A535452 0040B418 77 3C JA SHORT 0040B456 0040B41A 817D F8 5254534A CMP DWORD PTR SS:[EBP-8],4A535452 0040B421 0F84 86000000 JE 0040B4AD 0040B427 817D F8 54414843 CMP DWORD PTR SS:[EBP-8],43484154 0040B42E 74 55 JE SHORT 0040B485 0040B430 817D F8 56443244 CMP DWORD PTR SS:[EBP-8],44324456 0040B437 74 65 JE SHORT 0040B49E 0040B439 817D F8 50583244 CMP DWORD PTR SS:[EBP-8],44325850 0040B440 74 57 JE SHORT 0040B499 0040B442 817D F8 4C545244 CMP DWORD PTR SS:[EBP-8],4452544C 0040B449 74 5D JE SHORT 0040B4A8 0040B44B 817D F8 52485344 CMP DWORD PTR SS:[EBP-8],44534852 0040B452 74 4F JE SHORT 0040B4A3 0040B454 EB 66 JMP SHORT 0040B4BC 0040B456 817D F8 50584553 CMP DWORD PTR SS:[EBP-8],53455850 0040B45D 74 58 JE SHORT 0040B4B7 0040B45F 817D F8 52485353 CMP DWORD PTR SS:[EBP-8],53534852 0040B466 74 4A JE SHORT 0040B4B2 0040B468 817D F8 4E423257 CMP DWORD PTR SS:[EBP-8],5732424E 0040B46F 74 23 JE SHORT 0040B494 0040B471 817D F8 50583357 CMP DWORD PTR SS:[EBP-8],57335850 0040B478 74 10 JE SHORT 0040B48A 0040B47A 817D F8 33524157 CMP DWORD PTR SS:[EBP-8],57415233 0040B481 74 0C JE SHORT 0040B48F 0040B483 EB 37 JMP SHORT 0040B4BC 0040B485 6A 0B PUSH 0B 0040B487 58 POP EAX 0040B488 EB 35 JMP SHORT 0040B4BF 0040B48A 6A 0A PUSH 0A 0040B48C 58 POP EAX 0040B48D EB 30 JMP SHORT 0040B4BF 0040B48F 6A 09 PUSH 9 0040B491 58 POP EAX 0040B492 EB 2B JMP SHORT 0040B4BF 0040B494 6A 08 PUSH 8 0040B496 58 POP EAX 0040B497 EB 26 JMP SHORT 0040B4BF 0040B499 6A 07 PUSH 7 0040B49B 58 POP EAX 0040B49C EB 21 JMP SHORT 0040B4BF 0040B49E 6A 06 PUSH 6 0040B4A0 58 POP EAX 0040B4A1 EB 1C JMP SHORT 0040B4BF 0040B4A3 6A 05 PUSH 5 0040B4A5 58 POP EAX 0040B4A6 EB 17 JMP SHORT 0040B4BF 0040B4A8 6A 04 PUSH 4 0040B4AA 58 POP EAX 0040B4AB EB 12 JMP SHORT 0040B4BF 0040B4AD 6A 03 PUSH 3 0040B4AF 58 POP EAX 0040B4B0 EB 0D JMP SHORT 0040B4BF 0040B4B2 6A 02 PUSH 2 0040B4B4 58 POP EAX 0040B4B5 EB 08 JMP SHORT 0040B4BF 0040B4B7 6A 01 PUSH 1 0040B4B9 58 POP EAX 0040B4BA EB 03 JMP SHORT 0040B4BF 0040B4BC 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0040B4BF C9 LEAVE 0040B4C0 C3 RETN [/code] is it just me, or was my original break-through switch cases a better idea? that is, if the compiler actually did it right. I can't get it to make a hash table instead of sequential cmp and jes. And if you've noticed, it's doing push imm8, sign extends to 32 bit pop register in order to move w/e constant value into eax. this is pretty small, (3 bytes) especially considering that mov can't take 8 bit values. movsx can, but it still turns out to be pretty big. This is obviously a size optimization, but how about speed? I've heard somewhere that xor eax, eax lea eax, [eax + blah] is the FASTEST way. Can anyone verify this? | December 28, 2007, 3:35 AM |
Kp | Have you tried with a compiler from the last five years? :p I just put your code through gcc 4.1.2 and it came out with something more in line with what you seem to want. | December 28, 2007, 4:12 AM |
BreW | [quote author=Kp link=topic=17237.msg175537#msg175537 date=1198815138] Have you tried with a compiler from the last five years? :p I just put your code through gcc 4.1.2 and it came out with something more in line with what you seem to want. [/quote] I haven't. However, i've been thinking of switching to Watcom C. I heard it generates the fastest code of all the modern compilers. For now.... I think it would be optimal if I use inline assembly for this, using fastcall as the calling convention. EDIT** How many ms can you get it down to for calling this function 10 million times, passing CLIENT_D2DV and 0? For me, if i use __fastcall, exactly 297 in debug, and 79 in release. | December 28, 2007, 5:02 AM |
Myndfyr | Well, the only other reason I can think of for the double MOV is thread-safety, where another thread may have updated the memory location but not the register (because a thread context switch wouldn't impact the register value). But, the code isn't exactly reentrant anyway. Compiling with VC 2008, with small-program optimization favored, this is what is generated (note, this is compiler-generated machine+assembly, not from IDA or a similar tool): [code] _GetIcon PROC ; COMDAT 00000 8a 44 24 08 mov al, BYTE PTR _flags$[esp-4] ;if (flags & 64) 00004 a8 40 test al, 64 ; 00000040H 00006 74 04 je SHORT $LN19@GetIcon 00008 6a 11 push 17 ; 00000011H 0000a 58 pop eax ; return 17; 0000b c3 ret 0 $LN19@GetIcon: 0000c a8 20 test al, 32 ; 00000020H 0000e 74 04 je SHORT $LN18@GetIcon 00010 6a 10 push 16 ; 00000010H 00012 58 pop eax 00013 c3 ret 0 $LN18@GetIcon: 00014 a8 08 test al, 8 00016 74 04 je SHORT $LN17@GetIcon 00018 6a 0f push 15 ; 0000000fH 0001a 58 pop eax 0001b c3 ret 0 $LN17@GetIcon: 0001c a8 04 test al, 4 0001e 74 04 je SHORT $LN16@GetIcon 00020 6a 0e push 14 ; 0000000eH 00022 58 pop eax 00023 c3 ret 0 $LN16@GetIcon: 00024 a8 02 test al, 2 00026 74 04 je SHORT $LN15@GetIcon 00028 6a 0d push 13 ; 0000000dH 0002a 58 pop eax 0002b c3 ret 0 $LN15@GetIcon: ; if (flags & 1) 0002c a8 01 test al, 1 0002e 74 04 je SHORT $LN14@GetIcon 00030 6a 0c push 12 ; 0000000cH 00032 58 pop eax 00033 c3 ret 0 $LN14@GetIcon: ; now we're out of the flags checking - this is clearly a divide-and-conquer strategy 00034 8b 4c 24 04 mov ecx, DWORD PTR _client$[esp-4] 00038 b8 52 54 53 4a mov eax, 1246975058 ; 4a535452H 0003d 3b c8 cmp ecx, eax 0003f 77 42 ja SHORT $LN22@GetIcon ; if client is w3xp, war3, w2bn, sshr, sexp 00041 74 3c je SHORT $LN3@GetIcon ; if client is jstr 00043 81 f9 54 41 48 43 cmp ecx, 1128808788 ; 43484154H 00049 74 30 je SHORT $LN11@GetIcon ; if client is chat 0004b 81 f9 56 44 32 44 cmp ecx, 1144144982 ; 44324456H 00051 74 24 je SHORT $LN6@GetIcon ; if client is d2dv 00053 81 f9 50 58 32 44 cmp ecx, 1144150096 ; 44325850H 00059 74 18 je SHORT $LN7@GetIcon ; if client is d2xp 0005b 81 f9 4c 54 52 44 cmp ecx, 1146246220 ; 4452544cH 00061 74 0c je SHORT $LN4@GetIcon ; if client is drtl 00063 81 f9 52 48 53 44 cmp ecx, 1146308690 ; 44534852H 00069 75 53 jne SHORT $LN12@GetIcon ; if no match 0006b 6a 05 push 5 ; if client is dshr 0006d 58 pop eax 0006e c3 ret 0 $LN4@GetIcon: 0006f 6a 04 push 4 00071 58 pop eax 00072 c3 ret 0 $LN7@GetIcon: 00073 6a 07 push 7 00075 58 pop eax 00076 c3 ret 0 $LN6@GetIcon: 00077 6a 06 push 6 00079 58 pop eax 0007a c3 ret 0 $LN11@GetIcon: 0007b 6a 0b push 11 ; 0000000bH 0007d 58 pop eax 0007e c3 ret 0 $LN3@GetIcon: 0007f 6a 03 push 3 00081 58 pop eax 00082 c3 ret 0 $LN22@GetIcon: 00083 81 f9 50 58 45 53 cmp ecx, 1397053520 ; 53455850H 00089 74 30 je SHORT $LN1@GetIcon ; sexp 0008b 81 f9 52 48 53 53 cmp ecx, 1397966930 ; 53534852H 00091 74 24 je SHORT $LN2@GetIcon ; sshr 00093 81 f9 4e 42 32 57 cmp ecx, 1462911566 ; 5732424eH 00099 74 18 je SHORT $LN8@GetIcon ; w2bn 0009b 81 f9 50 58 33 57 cmp ecx, 1462982736 ; 57335850H 000a1 74 0c je SHORT $LN10@GetIcon ; w3xp 000a3 81 f9 33 52 41 57 cmp ecx, 1463898675 ; 57415233H 000a9 75 13 jne SHORT $LN12@GetIcon ; no match 000ab 6a 09 push 9 ; war3 000ad 58 pop eax 000ae c3 ret 0 $LN10@GetIcon: 000af 6a 0a push 10 ; 0000000aH 000b1 58 pop eax 000b2 c3 ret 0 $LN8@GetIcon: 000b3 6a 08 push 8 000b5 58 pop eax 000b6 c3 ret 0 $LN2@GetIcon: 000b7 6a 02 push 2 000b9 58 pop eax 000ba c3 ret 0 $LN1@GetIcon: 000bb 33 c0 xor eax, eax 000bd 40 inc eax $LN12@GetIcon: 000be c3 ret 0 _GetIcon ENDP [/code] That seems pretty tight to me considering all of the short jumps; no thrashing the processor instruction queue (in fact I bet the processor can probably execute a lot of these simultaneously). The theme of optimization for fast code (as opposed to small) seems to be moving whole machine words into registers, rather than pushing and popping. For example, mov eax, 17 (the code if flags & 64), is b8 11 00 00 00, whereas push 17 / pop eax is 6a 11 58, so a savings of two bytes is achieved by optimizing for code size. Someone who knows: is it possible to do a short jump by index? Besides, since the key to your hash table would be one of a few very large numbers, you'd probably have difficulty unless you made a clever hashing function, and that'd be pretty wasteful. Jump tables seem to be most useful when the numbers are sequential, or at least relatively close together. | December 28, 2007, 9:05 AM |
TheMinistered | I think I might also point out how bad brew's code is. I will repost his code below for easy reference as I make my point. [code] unsigned int GetIcon(unsigned long client, unsigned long flags) { unsigned int rettemp = 0; switch (client) { case CLIENT_CHAT: //0x43484154: rettemp++; case CLIENT_W3XP: //0x57335850: rettemp++; case CLIENT_WAR3: //0x57415233: rettemp++; case CLIENT_W2BN: //0x5732424E: rettemp++; case CLIENT_D2XP: //0x44325850: rettemp++; case CLIENT_D2DV: //0x44324456: rettemp++; case CLIENT_DSHR: //0x44534852: rettemp++; case CLIENT_DRTL: //0x4452544C: rettemp++; case CLIENT_JSTR: //0x4A535452: rettemp++; case CLIENT_SSHR: //0x53534852: rettemp++; case CLIENT_SEXP: //0x53455850: rettemp++; } if ((flags & 1) == 1) rettemp = 12; if ((flags & 2) == 2) rettemp = 13; if ((flags & 4) == 4) rettemp = 14; if ((flags & 8) == 8) rettemp = 15; if ((flags & 32) == 32) rettemp = 16; if ((flags & 64) == 64) rettemp = 17; return rettemp; } [/code] Well really I have only one good point. I don't think anyone touched on this directly, but they beat around the bush a little. In my opinion, that switch statement shouldn't be there at all. The statement itself has no part in "getting the icon" so it is just extra code that does nothing really, as you can see rettemp is later written over in one of the following if statements. So assuming his code actually works, this should be more effecient. [code] unsigned int GetIcon(unsigned long flags) { unsigned int rettemp = 1; if ((flags & 1) == 1) rettemp = 12; if ((flags & 2) == 2) rettemp = 13; if ((flags & 4) == 4) rettemp = 14; if ((flags & 8) == 8) rettemp = 15; if ((flags & 32) == 32) rettemp = 16; if ((flags & 64) == 64) rettemp = 17; return rettemp; } [/code] Hell, you really shouldn't even need a local variable to store the result in. You could probaly just do return #; | January 4, 2008, 6:01 AM |
l2k-Shadow | actually... the switch statement does change it. Since he doesn't break after his case. If the client is CLIENT_CHAT, it would rettemp++ as many times as there are cases, ending up with rettemp = 11 at the end. so even if the flags were 0, it would still change it. of course if the flags were not 0, it's useless code. | January 4, 2008, 6:18 AM |
FrOzeN | Being that brew is all about being a perforance nazi, wouldn't you want to be parsing the client/flags by reference? Also, by returning a value once the value is attained breaks it out of the function, which I assume would also be faster than continuing on. Another note, you should probably create more constants as to remove the need of magic numbers. The following should run a little faster: [code]unsigned int GetIcon(unsigned long &client, unsigned long &flags) { if (flags & 1) // Blizzard Representative return 12; if (flags & 8) // Battle.net Administrator return 15; if (flags & 2) // Channel Operator return 13; if (flags & 4) // Speaker return 14; if (flags & 64) // Special Guest return 17; if (flags & 32) // Squelched return 16 switch (client) { case CLIENT_CHAT: // 0x43484154 return 11; case CLIENT_W3XP: // 0x57335850 return 10; case CLIENT_WAR3: // 0x57415233 return 9; case CLIENT_W2BN: // 0x5732424E return 8; case CLIENT_D2XP: // 0x44325850 return 7; case CLIENT_D2DV: // 0x44324456 return 6; case CLIENT_DSHR: // 0x44534852 return 5; case CLIENT_DRTL: // 0x4452544C return 4; case CLIENT_JSTR: // 0x4A535452 return 3; case CLIENT_SSHR: // 0x53534852 return 2 case CLIENT_SEXP: // 0x53455850 return 1; } return 0; // Unknown Icon }[/code] [EDIT] Another thing you could do brew, is to run some statistics on Battle.net, and then determine which game clients are more commonly used. That way you could order your switch statement to have the ones that occur more higher up. Maybe you'll save one or two billionths of millisecond! | January 4, 2008, 9:02 AM |
JoeTheOdd | [quote author=FrOzeN link=topic=17237.msg175591#msg175591 date=1199437371] Another thing you could do brew, is to run some statistics on Battle.net, and then determine which game clients are more commonly used. That way you could order your switch statement to have the ones that occur more higher up. Maybe you'll save one or two billionths of millisecond! [/quote] hifive. | January 4, 2008, 11:25 AM |
Myndfyr | That would probably be inaccurate, since most bot users will idle in channels that aren't composed of the population represented in public Bnet channels. [quote author=TheMinistered link=topic=17237.msg175589#msg175589 date=1199426488] Well really I have only one good point. I don't think anyone touched on this directly, but they beat around the bush a little. In my opinion, that switch statement shouldn't be there at all. The statement itself has no part in "getting the icon" so it is just extra code that does nothing really, as you can see rettemp is later written over in one of the following if statements. [/quote] Shadow is correct; the switch statement does work. However, I'm also in agreement that he should just set/return the values in the switch statement, not rely on fallthrough (which is generally considered poor language practice). | January 4, 2008, 4:33 PM |
BreW | I love how everyone attempted to attack me in this topic. First off: TheMinistered, I have updated my code so that it checks for any flags first. What I tried to do was simple, utilize break-through so that it would execute however many temp++s there are (at the time it looked attractive to me-- inc eax takes one byte), and IMO it looked silly for sequential cases to return sequential static values. It didn't work out like that however. What I was outraged about this was how the compiler places two movs after every case. I was hoping it would see what I am doing, and use eax in lieu of that variable. Because I've always taken for granted that the compiler writes the optimal code for the situation, I was shellshocked to discover this when checking out what it compiled to. I tried writing my own equivalent in assembly, and using my break-through method, it actually takes 33% longer to execute then it would if I returned static values (the compiler ends up changing it to push 8bit, pop eax). Sure, the code ends up being 2 bytes bigger for every case there is, but in my opinion, speed is much more valuable then memory usage here. And frozen: Why would i want to be parsing the client/flags by refrence? Do you understand what you're talking about? Do you get what passing something by refrence actually means? Do you know how the compiler accomplishes that? | January 4, 2008, 8:32 PM |
Quarantine | Everyone attacked you in hopes you'd realize how silly you're being. | January 5, 2008, 7:15 AM |
FrOzeN | [quote author=brew link=topic=17237.msg175605#msg175605 date=1199478765]And frozen: Why would i want to be parsing the client/flags by refrence? Do you understand what you're talking about? Do you get what passing something by refrence actually means? Do you know how the compiler accomplishes that?[/quote]So, I've only been learning C++ less than two weeks and I figured parsing something by it's address is faster than creating a new value and copying the data across. A fairly logical assumption in my opinion. Anyway, I decided to run some benchmarks to see the difference in speed. It wasn't until I ran it through 100 million iterations before I started noticing a reasonable difference (ie. 50 milliseconds). Seriously, you're wasting so much time optimizing code that already runs at the speed of light. | January 5, 2008, 8:06 AM |
BreW | [quote author=FrOzeN link=topic=17237.msg175619#msg175619 date=1199520399] So, I've only been learning C++ less than two weeks and I figured parsing something by it's address is faster than creating a new value and copying the data across. A fairly logical assumption in my opinion. [/quote] Protip: it's not. You figured wrong. What if i wanted to make it fastcall? I'd be forcing the compiler to make the flags and ping actual variables on the stack if it already weren't a variable (note: the stack is slow when compared to registers) in order to lea the address into the variable, then it'd have to use mov eax, dword ptr [eax] anyways in order to do the cmp, where i could've just left it as eax. end of story. All of that adds up to take many more instructions then you'd think. Sure, it may seem like such a small improvement on performance, but what you have said, right here, is the REASON why computers never got faster. We take for granted that our processors can handle extra instructions like nothing, ignorant to the fact that all of this builds up over time, and our once lightning-fast programs become more akin to turtles then rabbits, with no real change in stability or productivity. Here is the evolution of microsoft windows: [code] Recommended specs- Version Speed | Ram | Disk space Windows 95 25 MHz | 8 MB | ~50 MB Windows 98 66 MHz | 24 MB | 140 – 255 MB Windows Me 150 MHz | 32 MB | 320 MB Windows 2000 Server 133 MHz | 64 MB | 1 GB Windows XP 300 MHz | 128 MB | 1.5 GB Windows Vista 1 GHz | 1 GB | 15 GB [/code] Have our ways of computing really changed since windows 2k? Yet look at that, it takes 16 times less RAM to run then vista, and 15 times less disk space. That is not only the result of more features, but because of bad programming practices as well. Back in the '70s if frozen said that, he would've been guilotined. Now today's world of software companies believe that it's product's success lies within the time it takes to produce and the number of useless features, further promoting high level programming languages and a slower end product. What fools. | January 5, 2008, 4:01 PM |
Leaky | [quote author=brew link=topic=17237.msg175623#msg175623 date=1199548872] Have our ways of computing really changed since windows 2k? Yet look at that, it takes 16 times less RAM to run then vista, and 15 times less disk space. That is not only the result of more features, but because of bad programming practices as well. Back in the '70s if frozen said that, he would've been guilotined. Now today's world of software companies believe that it's product's success lies within the time it takes to produce and the number of useless features, further promoting high level programming languages and a slower end product. What fools. [/quote] WHAT??? you mean it's not a good success strategy to make my bots able to grate cheese? | January 5, 2008, 4:13 PM |
St0rm.iD | You guys are both retarded. - brew is being silly in order to prove how awesome he is - passing a long by reference is silly. at least on my machine, a long is a processor word and therefore fits in a register. the compiler would probably pass it in a register. if you're passing it by reference, it has to be stored in memory and can't be stored in a register which is much faster. if a long was NOT a machine word, however, it would be faster to pass by reference as you'd only pass the memory address rather than copying the memory on to the stack. In essence, frozen was almost correct. brew, I agree in the hardware software conspiracy, but I think you're just being an asshole. | January 5, 2008, 4:57 PM |
BreW | [quote author=Banana fanna fo fanna link=topic=17237.msg175625#msg175625 date=1199552246] if a long was NOT a machine word, however, it would be faster to pass by reference as you'd only pass the memory address rather than copying the memory on to the stack. [/quote] [quote author=Banana fanna fo fanna link=topic=17237.msg175625#msg175625 date=1199552246] if a long was NOT a machine word, however, it would be faster to pass by reference [/quote] [quote author=Banana fanna fo fanna link=topic=17237.msg175625#msg175625 date=1199552246] if a long was NOT a machine word [/quote] Suprise, it is! Say the machine word was 64 bits. What's that going to change? Is it faster to push the 64-bit address onto the stack or pass the 32 bit number by value? cough*zero extend*cough. If the case here would be opposite, (apparently you're using a 16 bit machine?) then yeah, i can see where you're going, but this code isn't MADE for dos. sorry. And before anyone attacks me about the size of a long, look here: http://en.wikipedia.org/wiki/Long_integer It's always 4 bytes, in the C programming language. Always. And before anyone says something about the size of a byte, it's ASSUMED TO BE 8 BITS. IF IT IS NOT 8 BITS, YOU AND YOUR COMPUTER MUST BE FROM CIRCA 1950. so shut up and don't try to get technical. | January 5, 2008, 6:36 PM |
l2k-Shadow | [quote author=brew link=topic=17237.msg175628#msg175628 date=1199558175] It's always 4 bytes, in the C programming language. Always. And before anyone says something about the size of a byte, it's ASSUMED TO BE 8 BITS. IF IT IS NOT 8 BITS, YOU AND YOUR COMPUTER MUST BE FROM CIRCA 1950. so shut up and don't try to get technical. [/quote] the data type sizes depend on the compiler and the data model of that compiler, so shut up and stop trying to say that you know everything when you don't. http://en.wikipedia.org/wiki/64_bit#64-bit_data_models | January 5, 2008, 7:55 PM |
St0rm.iD | [quote author=brew link=topic=17237.msg175628#msg175628 date=1199558175] [quote author=Banana fanna fo fanna link=topic=17237.msg175625#msg175625 date=1199552246] if a long was NOT a machine word, however, it would be faster to pass by reference as you'd only pass the memory address rather than copying the memory on to the stack. [/quote] [quote author=Banana fanna fo fanna link=topic=17237.msg175625#msg175625 date=1199552246] if a long was NOT a machine word, however, it would be faster to pass by reference [/quote] [quote author=Banana fanna fo fanna link=topic=17237.msg175625#msg175625 date=1199552246] if a long was NOT a machine word [/quote] Suprise, it is! Say the machine word was 64 bits. What's that going to change? Is it faster to push the 64-bit address onto the stack or pass the 32 bit number by value? cough*zero extend*cough. If the case here would be opposite, (apparently you're using a 16 bit machine?) then yeah, i can see where you're going, but this code isn't MADE for dos. sorry. And before anyone attacks me about the size of a long, look here: http://en.wikipedia.org/wiki/Long_integer It's always 4 bytes, in the C programming language. Always. And before anyone says something about the size of a byte, it's ASSUMED TO BE 8 BITS. IF IT IS NOT 8 BITS, YOU AND YOUR COMPUTER MUST BE FROM CIRCA 1950. so shut up and don't try to get technical. [/quote] no shit, pledge. i hope you aren't critiquing me. i was saying that i think frozen was confused about the size of a unsigned long. | January 5, 2008, 8:38 PM |
BreW | [quote author=l2k-Shadow link=topic=17237.msg175629#msg175629 date=1199562954] [quote author=brew link=topic=17237.msg175628#msg175628 date=1199558175] It's always 4 bytes, in the C programming language. Always. And before anyone says something about the size of a byte, it's ASSUMED TO BE 8 BITS. IF IT IS NOT 8 BITS, YOU AND YOUR COMPUTER MUST BE FROM CIRCA 1950. so shut up and don't try to get technical. [/quote] the data type sizes depend on the compiler and the data model of that compiler, so shut up and stop trying to say that you know everything when you don't. http://en.wikipedia.org/wiki/64_bit#64-bit_data_models [/quote] I didn't say I know everything. I'm just saying that I'm tired of people picking out small stupid little details and making a huge deal out of it. This exact thing happened to me at least 3 times this week. I'm physically TIRED of arguing about the size of data types. I'm sorry, I misread that wiki article. My point was that frozen really was wrong, banana tried to back him up though saying he wasn't entirely wrong. No, he wasn't. But the case that banana presented where frozen wouldn't be wrong is just hardly ever seen in practice. I was just pointing that out. and wtf is with me being the pledge, i'm not the pledge. okay??? | January 5, 2008, 9:24 PM |
Myndfyr | [quote author=brew link=topic=17237.msg175623#msg175623 date=1199548872] [Protip:[/quote] LOL Please. [quote author=FrOzeN link=topic=17237.msg175619#msg175619 date=1199520399] So, I've only been learning C++ less than two weeks and I figured parsing something by it's address is faster than creating a new value and copying the data across. A fairly logical assumption in my opinion.[/quote] You're incorrect in this case. Here's what happens when you call a function: Local stack variables being passed by value are copied onto the stack, usually padded to 4 or 8 bytes depending on the architecture. For example: [code] int a = 10; func(a); [/code] Local stack variables being passed by reference have their addresses copied onto the stack, always 4 or 8 bytes depending on the architecture. Example: [code] int a = 10; func(&a); [/code] Local heap variables being passed by value are copied onto the stack, always 4 or 8 bytes depending on the architecture. Example: [code] CString* str = new CString; str("Blaaaaarrgh"); func(str); // changes made to the parameter affect the object pointed-to by the str pointer. [/code] Local heap variables being passed by reference (for instance, to change the address of a pointer inside of a function) have their addresses in the local function passed to the callee. Example: [code] CString* str = new CString; str("Blaaaaaaaaaaaaaaaaaarrgh!"); func(&str); [/code] In the second and fourth examples, passing by reference allows you to modify the variable internal to the calling function - the actual pointer will be different in the fourth example. Passing variables by reference is really only faster when it involves copying a value larger than the machine pointer size. | January 5, 2008, 9:55 PM |
BreW | [quote author=MyndFyre[vL] link=topic=17237.msg175632#msg175632 date=1199570154] [quote author=brew link=topic=17237.msg175623#msg175623 date=1199548872] Protip:[/quote] LOL Please. [/quote] wat? it's a 4chan meme that was just all too easy to insert ITT. for those of you who don't know, here is the original image: [img]http://img136.imageshack.us/img136/2443/protipbq5.jpg[/img] | January 5, 2008, 10:54 PM |
MyStiCaL | i think my IQ just dropped. | January 6, 2008, 12:42 AM |
FrOzeN | [quote author=l2k-Shadow link=topic=17237.msg175629#msg175629 date=1199562954] [quote author=brew link=topic=17237.msg175628#msg175628 date=1199558175] It's always 4 bytes, in the C programming language. Always. And before anyone says something about the size of a byte, it's ASSUMED TO BE 8 BITS. IF IT IS NOT 8 BITS, YOU AND YOUR COMPUTER MUST BE FROM CIRCA 1950. so shut up and don't try to get technical. [/quote] the data type sizes depend on the compiler and the data model of that compiler, so shut up and stop trying to say that you know everything when you don't. http://en.wikipedia.org/wiki/64_bit#64-bit_data_models [/quote]Shouldn't data types be independent of the compiler? Instead, follow the rules of the language? (At least if you're using Stardard C++) From the way I've seen it so far, it goes like this: Short and long aren't data types, they are data type modifiers. A short is actually shorthand for short int which should force an integer to be 16-bit. A long is short for a long int which forces it to be 32-bit. An int without a data type modifier should be either 16 or 32 bits depending on the system. Also, ISO C++ 99 introduces the use of long long int which forces a 64-bit integer. --- Coming to think of how it all works, it does make sense now that parsing a value smaller or equal to the size of an address would be faster. You can thank VB6 for indoctrinating me with "ByRef is always faster than ByVal" shit. Maybe the way VB6 handles data types that statement would be true for the most part, unfortunately I brought the concept with me to C++ without much of a thought. | January 6, 2008, 3:24 AM |
Kp | As I recall, the rules of the language are somewhat vague on that point. A short int is not larger than an int and a long int is not smaller than an int. The standard does not declare that a long int must be 32 bits. Further, the standard does not declare that an int must be the size of a short int or the size of a long int. On an AMD64 platform, gcc implements int as 32 bits and long int as 64 bits. See the description of -m32 and -m64 in info gcc for details. | January 6, 2008, 5:01 AM |
FrOzeN | Ah ok, I'll have a look into this. --- Anyway brew, now that you've recovered that nanosecond, why don't you fix the logic error in your program. For example, displaying the icon for a channel operator has more precedence than a squelched user. At least the code I posted works correctly (well, apart from the two missing semi-colons which I would of noticed upon compiling). | January 6, 2008, 7:59 AM |
Quarantine | [quote author=brew link=topic=17237.msg175623#msg175623 date=1199548872] Have our ways of computing really changed since windows 2k? Yet look at that, it takes 16 times less RAM to run then vista, and 15 times less disk space. That is not only the result of more features, but because of bad programming practices as well. Back in the '70s if frozen said that, he would've been guilotined. Now today's world of software companies believe that it's product's success lies within the time it takes to produce and the number of useless features, further promoting high level programming languages and a slower end product. What fools. [/quote] Of course they have, that's something that hopefully you could see. There have been many advancements both hardware and software in computing. How can you draw the conclusion that the resource requirements are a result of bad programming? It's definitely a possibility, but it's impossible for you to definitively know that due to the closed nature of the Windows Operating System. It's impossible to know for sure, but it is possible to take a reasonable guess. I think this is what you're doing, or at least trying to do. The difference is, the toolchain for Windows has not really changed much since the Windows 2k days. The Core OS much less, it's compiled from the same language today that it was back then. Give or take a component or two. The really high level .NET stuff has not been implemented extensively in Windows yet, as far as components are concerned. How can you talk about bad programming practices, you. I'd understand if it was somebody with a degree, or a fair amount of experience but you? You've barely gotten your feet wet in the world of programming when compared to the programmers at Redmond. The world of technology evolves rather quickly, and as things like digital entertainment become more and more a part of everyday life they will continue to climb. People want the innovations of tomorrow, yesterday. If they don't get them they complain that the market is stagnated, if they do get them then they complain about the inherent need to upgrade your hardware. In short, I do think there is a fair amount of logic in your stance about High Level bloat, I just think you take it to an extreme. At a point you trade off functionality for raw speed, even if the speed gain is negligible. Come on man, we're in the era of Dual (even Quad) core processing. What's not to like? | January 6, 2008, 8:43 AM |
BreW | [quote author=FrOzeN link=topic=17237.msg175649#msg175649 date=1199606340] Anyway brew, now that you've recovered that nanosecond, why don't you fix the logic error in your program. For example, displaying the icon for a channel operator has more precedence than a squelched user. At least the code I posted works correctly (well, apart from the two missing semi-colons which I would of noticed upon compiling). [/quote] You know what's funny? It worked the first time. Remember? But you changed it to use static returns yourself. What's even funnier is this: [quote author=brew link=topic=17237.msg175535#msg175535 date=1198812950] grr. okay, so i did what myndfyre suggested. now it looks like this: [code] unsigned int GetIcon(unsigned long client, unsigned long flags) { if (flags & 64) return 17; if (flags & 32) return 16; if (flags & 8) return 15; if (flags & 4) return 14; if (flags & 2) return 13; if (flags & 1) return 12; switch (client) { case CLIENT_CHAT: //0x43484154: return 11; case CLIENT_W3XP: //0x57335850: return 10; case CLIENT_WAR3: //0x57415233: return 9; case CLIENT_W2BN: //0x5732424E: return 8; case CLIENT_D2XP: //0x44325850: return 7; case CLIENT_D2DV: //0x44324456: return 6; case CLIENT_DSHR: //0x44534852: return 5; case CLIENT_DRTL: //0x4452544C: return 4; case CLIENT_JSTR: //0x4A535452: return 3; case CLIENT_SSHR: //0x53534852: return 2; case CLIENT_SEXP: //0x53455850: return 1; } } [/code] [/quote] Honestly. If someone's going to post in a topic, they should read the entire thing before posting. | January 6, 2008, 1:55 PM |
FrOzeN | [quote author=brew link=topic=17237.msg175651#msg175651 date=1199627736] [quote author=FrOzeN link=topic=17237.msg175649#msg175649 date=1199606340] Anyway brew, now that you've recovered that nanosecond, why don't you fix the logic error in your program. For example, displaying the icon for a channel operator has more precedence than a squelched user. At least the code I posted works correctly (well, apart from the two missing semi-colons which I would of noticed upon compiling). [/quote] You know what's funny? It worked the first time.[/quote]No, the logic in your first code is only more correct than your revision of it. It is still not completely right. Maybe you should have a look at the flag specifications. Secondly, MyndFyre suggested for you to put your flags check above your switch statement, not to completely reverse your flag check. | January 6, 2008, 2:02 PM |
BreW | [quote author=FrOzeN link=topic=17237.msg175652#msg175652 date=1199628149] [quote author=brew link=topic=17237.msg175651#msg175651 date=1199627736] [quote author=FrOzeN link=topic=17237.msg175649#msg175649 date=1199606340] Anyway brew, now that you've recovered that nanosecond, why don't you fix the logic error in your program. For example, displaying the icon for a channel operator has more precedence than a squelched user. At least the code I posted works correctly (well, apart from the two missing semi-colons which I would of noticed upon compiling). [/quote] You know what's funny? It worked the first time.[/quote]No, the logic in your first code is only more correct than your revision of it. It is still not completely right. Maybe you should have a look at the flag specifications. Secondly, MyndFyre suggested for you to put your flags check above your switch statement, not to completely reverse your flag check. [/quote] I reversed it like that in order to keep the flag precedence, actually. Sorry, it's just that i'd like to see who's squelched etc over channel operator (i have other things to show all the flags). IIRC a number of other bots do this as well. My bot doesn't follow the standards-- so what? it also has three columns instead of two, and the listview name coloring isn't the same as starcraft's either. I thought the topic here was supposed to be about how that code was compiled to that pos assembly that you saw in the first post, not the logic of my function based on the "standard". | January 6, 2008, 2:12 PM |
Quarantine | [quote author=brew link=topic=17237.msg175653#msg175653 date=1199628769] [quote author=FrOzeN link=topic=17237.msg175652#msg175652 date=1199628149] [quote author=brew link=topic=17237.msg175651#msg175651 date=1199627736] [quote author=FrOzeN link=topic=17237.msg175649#msg175649 date=1199606340] Anyway brew, now that you've recovered that nanosecond, why don't you fix the logic error in your program. For example, displaying the icon for a channel operator has more precedence than a squelched user. At least the code I posted works correctly (well, apart from the two missing semi-colons which I would of noticed upon compiling). [/quote] You know what's funny? It worked the first time.[/quote]No, the logic in your first code is only more correct than your revision of it. It is still not completely right. Maybe you should have a look at the flag specifications. Secondly, MyndFyre suggested for you to put your flags check above your switch statement, not to completely reverse your flag check. [/quote] I reversed it like that in order to keep the flag precedence, actually. Sorry, it's just that i'd like to see who's squelched etc over channel operator (i have other things to show all the flags). IIRC a number of other bots do this as well. My bot doesn't follow the standards-- so what? it also has three columns instead of two, and the listview name coloring isn't the same as starcraft's either. I thought the topic here was supposed to be about how that code was compiled to that pos assembly that you saw in the first post, not the logic of my function based on the "standard". [/quote] lol brew is trying to justify incorrect code. lolol "so what" | January 6, 2008, 5:12 PM |
BreW | [quote author=Warrior link=topic=17237.msg175655#msg175655 date=1199639525] lol brew is trying to justify incorrect code. lolol "so what" [/quote] incorrect? by whos standards? i obviously intended for my code to be executed in that manner and return those results. | January 6, 2008, 6:13 PM |
Quarantine | [quote author=brew link=topic=17237.msg175656#msg175656 date=1199643213] [quote author=Warrior link=topic=17237.msg175655#msg175655 date=1199639525] lol brew is trying to justify incorrect code. lolol "so what" [/quote] incorrect? by whos standards? i obviously intended for my code to be executed in that manner and return those results. [/quote] obviously. when emulating a client it's often best to actually not fail at implementing features in the way the client does (that's the point of emulation isn't it)? unless you're admitting that you're bad at emulating a client (surprise, surprise), and just make pointless topics to show off whatever table scraps you've taken from the left overs things other people have done, tried, and realized to be a waste of time years ago. obviously | January 6, 2008, 7:20 PM |
BreW | [quote author=Warrior link=topic=17237.msg175658#msg175658 date=1199647216] [quote author=brew link=topic=17237.msg175656#msg175656 date=1199643213] [quote author=Warrior link=topic=17237.msg175655#msg175655 date=1199639525] lol brew is trying to justify incorrect code. lolol "so what" [/quote] incorrect? by whos standards? i obviously intended for my code to be executed in that manner and return those results. [/quote] obviously. when emulating a client it's often best to actually not fail at implementing features in the way the client does (that's the point of emulation isn't it)? unless you're admitting that you're bad at emulating a client (surprise, surprise), and just make pointless topics to show off whatever table scraps you've taken from the left overs things other people have done, tried, and realized to be a waste of time years ago. obviously [/quote] Wow, you're a real pisser. You know that? First off, I'm pretty sure that a game emulator for my own personal use doesn't NEED to use StarCraft's flag parsing scheme. I'm bad at emulating a client? How do you know that? Please, just shut up. You entered the topic on a good note. What you said was something I hoped to get from other members, but apparently that wasn't the case. If you don't have anything constructive to say, why say it at all? Was this a pointless topic? Its purpose was not to "show off table scraps", it just so happened that I found the perfect example of what this topic is about from my battle.net chatter bot. | January 6, 2008, 8:28 PM |
Myndfyr | [quote author=Warrior link=topic=17237.msg175658#msg175658 date=1199647216] obviously. when emulating a client it's often best to actually not fail at implementing features in the way the client does (that's the point of emulation isn't it)? unless you're admitting that you're bad at emulating a client (surprise, surprise), and just make pointless topics to show off whatever table scraps you've taken from the left overs things other people have done, tried, and realized to be a waste of time years ago. obviously [/quote] Shut up, War. Mock him when he's wrong about something. | January 7, 2008, 12:19 AM |
Quarantine | [quote author=MyndFyre[vL] link=topic=17237.msg175673#msg175673 date=1199665190] [quote author=Warrior link=topic=17237.msg175658#msg175658 date=1199647216] obviously. when emulating a client it's often best to actually not fail at implementing features in the way the client does (that's the point of emulation isn't it)? unless you're admitting that you're bad at emulating a client (surprise, surprise), and just make pointless topics to show off whatever table scraps you've taken from the left overs things other people have done, tried, and realized to be a waste of time years ago. obviously [/quote] Shut up, War. Mock him when he's wrong about something. [/quote] Let me have some fun, ok? | January 7, 2008, 12:25 AM |
JoeTheOdd | [quote author=MyndFyre[vL] link=topic=17237.msg175600#msg175600 date=1199464404] not rely on fallthrough (which is generally considered poor language practice). [/quote] Some languages don't even allow fallthrough, which I didn't initially like, but I see the point of now. I'm not sure which language it was, but... oww.. feel the pain from saying this.. I think it was VB. | January 7, 2008, 10:51 AM |
Quarantine | C# | January 7, 2008, 11:23 AM |
JoeTheOdd | Warrior wins. Does VB allow fallthrough, though? | January 7, 2008, 2:31 PM |
BreW | [quote author=Joe[x86] link=topic=17237.msg175697#msg175697 date=1199716311] Does VB allow fallthrough, though? [/quote] No | January 7, 2008, 8:08 PM |