Results 1 to 21 of 21

Thread: [RESOLVED] CCur Function

  1. #1

    Thread Starter
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    9,988

    Resolved [RESOLVED] CCur Function

    I am trying to convert a piece of VB6 code and running into a Function that I'm not familiar with, the CCur function.

    According to the documentation (here) it looks as if the currency data type is unique in a few ways:
    • If a number can be converted to an Integer, it will represented as such. E.g. "1" will transform to 1 and not 1.0
    • Arithmetic of the Currency data type will be dependent on culture. E.g. 100,123 will be treated as one hundred point one, two, three if the culture of my computer is set to have commas represent decimal places.


    Is this more or less correct, or am I missing something?

  2. #2
    PowerPoster
    Join Date
    Feb 2006
    Posts
    21,864

    Re: CCur Function

    No, the Currency data type doesn't "contain punctuation." You seem to be confusing it with text representations of such values.

    This type is a 64-bit signed integer with implied scaling by 10000 to provide "4 digits" of fractional precision.

    If you feed CCur() a String value then yes, it is locale-aware just like CStr() and they'll both apply that when parsing/formatting text to/from Currency.

    CStr() does not format with redundant characters, so of course 1@ formats as "1" and not "1.0" just as you said.

    Text representations have no bearing on the arithmetic.

  3. #3

    Thread Starter
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    9,988

    Re: CCur Function

    Ok, so essentially it is a decimal with higher precision for the first four digit?

  4. #4
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    6,585

    Re: CCur Function

    dday9,

    It's truly just an 8-byte 2's compliment signed integer. In many ways it's exactly the same as the LongLong seen in the VBA.

    It's just that, when it's printed (or input), VB6 will always insert a decimal point at the fourth spot from the right. Internally, there's nothing about it that's a floating point number.

    We often use them as 8-byte signed integers.

    EDIT: I guess one way to think about it is as a fixed point number, fixed at that fourth decimal spot.
    Last edited by Elroy; Jan 14th, 2021 at 10:33 AM.
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  5. #5
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    6,021

    Re: CCur Function

    Quote Originally Posted by dday9 View Post
    Ok, so essentially it is a decimal with higher precision for the first four digit?
    A Currency is basically a more primitive version of .Net's Decimal type. Like the Decimal type, it also uses some kind of fixed point math internally.

    EDIT:

    The Decimal type actually uses something called Decimal floating point which is somewhat related to fixed point math.
    Last edited by Niya; Jan 15th, 2021 at 05:23 PM.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  6. #6
    PowerPoster
    Join Date
    Feb 2006
    Posts
    21,864

    Re: CCur Function

    Decimal is entirely different. VB6 supports Decimal, but only as a Variant subtype.

    https://docs.microsoft.com/en-us/ope...c-81c1f5c331b2

  7. #7
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    6,585

    Re: CCur Function

    MMMMmmm, I wouldn't have said "entirely" different.

    Currency is an 8-byte 2's compliment integer with a decimal stuck in at the fourth (from right) spot. It's all base-10, which makes it very nice when you only need a few decimal places but high precision.

    Decimal is basically a 12-byte integer with a separate sign bit (not 2's compliment). And it also has a byte for specifying a base-10 decimal point, but only from 10^28 to 10^-28. It's restricted like that so that the actual number preserves a "full" 28 digits of exact precision, regardless of where the decimal point is.

    I guess I see them as similar because they both try to preserve a base-10 sense about them, where as IEEE singles and IEEE doubles are truly base-2 creatures.

    EDIT: Ohhh, and just FYI, math with currency is lightning fast because it's all just integer math typically done in registers (with a bit of overflow protection). However, math with Decimal types is going to be magnitudes slower for several reasons: 1) you've got to pull it out of a Variant, 2) the byte Endianness isn't preserved on them (Hi32, Lo32, Mid32), and 3) the floating point co-processors have no idea what these things are.

    So, maybe not "entirely" different, but yeah, "pretty" different.
    Last edited by Elroy; Jan 15th, 2021 at 11:36 PM.
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  8. #8
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Posts
    2,694

    Re: CCur Function

    Quote Originally Posted by Elroy View Post
    math with currency is lightning fast because it's all just integer math typically done in registers (with a bit of overflow protection).
    I just compiled c3 = c1 * c2 with all Currency variables and here is the disassembly

    Code:
        c3 = c1 * c2
    00401BF0 FF 75 C0             push        dword ptr [ebp-40h]  
    00401BF3 FF 75 BC             push        dword ptr [c2]  
    00401BF6 FF 75 C8             push        dword ptr [ebp-38h]  
    00401BF9 FF 75 C4             push        dword ptr [c1]  
    00401BFC E8 93 F5 FF FF       call        ___vbaCyMul (401194h)  
    00401C01 89 45 B4             mov         dword ptr [c3],eax  
    00401C04 89 55 B8             mov         dword ptr [ebp-48h],edx
    So both c1 and c2 are pushed on stack as normal parameters and the actual multiplication is a function call, not a single instruction operating on registers.

    Here is a disassembly of ___vbaCyMul

    Code:
    __vbaCyMul:
    6AF35D34 55                   push        ebp  
    6AF35D35 8B EC                mov         ebp,esp  
    6AF35D37 83 C4 F8             add         esp,0FFFFFFF8h  
    6AF35D3A D9 2D 68 60 F4 6A    fldcw       word ptr ds:[6AF46068h]  
    6AF35D40 DF 6D 10             fild        qword ptr [ebp+10h]  
    6AF35D43 DF 6D 08             fild        qword ptr [ebp+8]  
    6AF35D46 DE C9                fmulp       st(1),st  
    6AF35D48 D8 35 1C 20 F5 6A    fdiv        dword ptr [__vbaAryVarVarg+16h (6AF5201Ch)]  
    6AF35D4E DF 7D F8             fistp       qword ptr [ebp-8]  
    6AF35D51 DF E0                fnstsw      ax  
    6AF35D53 A8 0D                test        al,0Dh  
    6AF35D55 0F 85 CB C2 01 00    jne         __vbaFPException+2 (6AF52026h)  
    6AF35D5B 8B 55 FC             mov         edx,dword ptr [ebp-4]  
    6AF35D5E 8B 45 F8             mov         eax,dword ptr [ebp-8]  
    6AF35D61 C9                   leave  
    6AF35D62 C2 10 00             ret         10h
    Looks like a lot of floating-point instructions underneath.

    cheers,
    </wqw>

  9. #9
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    6,021

    Re: CCur Function

    Quote Originally Posted by wqweto View Post
    I just compiled c3 = c1 * c2 with all Currency variables and here is the disassembly

    Code:
        c3 = c1 * c2
    00401BF0 FF 75 C0             push        dword ptr [ebp-40h]  
    00401BF3 FF 75 BC             push        dword ptr [c2]  
    00401BF6 FF 75 C8             push        dword ptr [ebp-38h]  
    00401BF9 FF 75 C4             push        dword ptr [c1]  
    00401BFC E8 93 F5 FF FF       call        ___vbaCyMul (401194h)  
    00401C01 89 45 B4             mov         dword ptr [c3],eax  
    00401C04 89 55 B8             mov         dword ptr [ebp-48h],edx
    So both c1 and c2 are pushed on stack as normal parameters and the actual multiplication is a function call, not a single instruction operating on registers.

    Here is a disassembly of ___vbaCyMul

    Code:
    __vbaCyMul:
    6AF35D34 55                   push        ebp  
    6AF35D35 8B EC                mov         ebp,esp  
    6AF35D37 83 C4 F8             add         esp,0FFFFFFF8h  
    6AF35D3A D9 2D 68 60 F4 6A    fldcw       word ptr ds:[6AF46068h]  
    6AF35D40 DF 6D 10             fild        qword ptr [ebp+10h]  
    6AF35D43 DF 6D 08             fild        qword ptr [ebp+8]  
    6AF35D46 DE C9                fmulp       st(1),st  
    6AF35D48 D8 35 1C 20 F5 6A    fdiv        dword ptr [__vbaAryVarVarg+16h (6AF5201Ch)]  
    6AF35D4E DF 7D F8             fistp       qword ptr [ebp-8]  
    6AF35D51 DF E0                fnstsw      ax  
    6AF35D53 A8 0D                test        al,0Dh  
    6AF35D55 0F 85 CB C2 01 00    jne         __vbaFPException+2 (6AF52026h)  
    6AF35D5B 8B 55 FC             mov         edx,dword ptr [ebp-4]  
    6AF35D5E 8B 45 F8             mov         eax,dword ptr [ebp-8]  
    6AF35D61 C9                   leave  
    6AF35D62 C2 10 00             ret         10h
    Looks like a lot of floating-point instructions underneath.

    cheers,
    </wqw>
    Good God this is slow as hell.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  10. #10

  11. #11
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    6,585

    Re: CCur Function

    This is all because VB6 is as old as heck, and doesn't take advantage of CPU capabilities we currently have. This is good to know though (about the Currency type). Hopefully, they don't do something crazy like that for Integer and Long math.

    And yeah, I would imaging that the dis-assembled assembly of Decimal math is dizzying.
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  12. #12
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,364

    Re: CCur Function

    yeah. vb6 is not the fastest, but still its pretty fast and not last in the list.
    its not that we need to use the currency or decimal type millions of times every second.
    sure, if we are making a program that is calculating mathematical formulas that requires decimals, VB6 would be slow comparing to C.
    also, the one part that is eating a lot of speed is graphics. that part we can fix by using directx.

  13. #13
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    6,021

    Re: CCur Function

    Not so fast. You guys are looking at it the wrong way. You have to think in terms of the right tool for the job. The Currency type is extremely bloated, true. The Decimal type might be even more slow. However, their purpose is not about performance, it's meant for stable financially calculations. Finances have a very low tolerance for rounding errors. I don't know about you guys but I can't see any application that deals with finance needing to perform intensive financial calculations in tight loops which is about the only way you would ever notice how dreadfully slow the Currency data type is.

    If you're modeling the whether in real time or writing a game engine then you need performance. You won't use data types like Currency for calculations in that domain. You may not even write such code yourself, you would use things like CUDA or DirectX.

    It's not about VB6 being old in this case because I'll tell you right now, .Net's Decimal type is even slower than Currency because all of it is implemented in managed code which means ultimately the disassembly would be even more bloated than what you see for the Currency type. I was also surprised to find that the .Net compiler as of Visual Studio 2013 still compiles floating point code to x87 FPU instructions instead of SSE. I don't know if this has changed with Visual Studio 2019. The thing is, it doesn't matter because the truth is, we really do not need bleeding edge performance 99% of the time. Decent performance is enough for most of the code we write so there is no need for them to be super optimized. One of the bad habits programmers tend to pick up at one point or another is believing we need to optimize everything all the time. We don't. If a piece of un-optimized code doesn't degrade the user experience, then the code is perfectly fine the way it is.
    Last edited by Niya; Jan 16th, 2021 at 03:22 PM.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  14. #14
    Frenzied Member
    Join Date
    Feb 2015
    Posts
    1,729

    Re: CCur Function

    Not so slow. It faster enough because there is no unnecessary instructions. Just the C code of __vbaCyMul:
    Code:
    signed __int64 __stdcall __vbaCyMul(__int64 a1, __int64 a2)
    {
      __int16 v2; // fps
    
      JUMPOUT(v2 & 0xD, 0, FpException);
      return (signed __int64)((double)a2 * (double)a1 / 10000.0);
    }
    Moreover if you use add/sub instructions they works like 64 bit arithmetic:
    Code:
    Sub Main()
    
        MsgBox addcy(123.12@, 43.23@)
        
    End Sub
    
    Function addcy(ByVal x As Currency, ByVal z As Currency) As Currency
        addcy = x + z
    End Function
    Asm:

    Code:
    CPU Disasm
    Address                        Hex dump          Command                                  Comments
    00401687 modMain::addcy        /$  8B4424 04     MOV EAX,DWORD PTR SS:[ARG.1]             ; StandardModule.modMain::addcy(void)
    0040168B                       |.  8B5424 08     MOV EDX,DWORD PTR SS:[ARG.2]
    0040168F                       |.  034424 0C     ADD EAX,DWORD PTR SS:[ARG.3]
    00401693                       |.  135424 10     ADC EDX,DWORD PTR SS:[ARG.4]
    00401697                       \.  C2 1000       RETN 10
    Just for comparison, the function:
    Code:
    int main() {
    	return (GetTickCount64() * GetTickCount64() / 10000);
    };
    Code:
    CPU Disasm
    Address   Hex dump          Command                                  Comments
    00101000  /$  53            PUSH EBX                                 ; INT mul64.<ModuleEntryPoint>(void)
    00101001  |.  56            PUSH ESI
    00101002  |.  8B35 00201000 MOV ESI,DWORD PTR DS:[<&KERNEL32.GetTick ; Jump to KERNELBASE.GetTickCount64
    00101008  |.  57            PUSH EDI
    00101009  |.  FFD6          CALL ESI
    0010100B  |.  8BF8          MOV EDI,EAX
    0010100D  |.  8BDA          MOV EBX,EDX
    0010100F  |.  FFD6          CALL ESI
    00101011  |.  52            PUSH EDX
    00101012  |.  50            PUSH EAX
    00101013  |.  53            PUSH EBX
    00101014  |.  57            PUSH EDI
    00101015  |.  E8 86000000   CALL _allmul                             ; [_allmul
    0010101A  |.  6A 00         PUSH 0
    0010101C  |.  68 10270000   PUSH 2710
    00101021  |.  52            PUSH EDX
    00101022  |.  50            PUSH EAX
    00101023  |.  E8 08000000   CALL _aulldiv                            ; [_aulldiv
    00101028  |.  5F            POP EDI
    00101029  |.  5E            POP ESI
    0010102A  |.  5B            POP EBX
    0010102B  \.  C3            RETN
    0010102C      CC            INT3
    0010102D      CC            INT3
    0010102E      CC            INT3
    0010102F      CC            INT3
    00101030  /$  53            PUSH EBX                                 ; mul64._aulldiv(void)
    00101031  |.  56            PUSH ESI
    00101032  |.  8B4424 18     MOV EAX,DWORD PTR SS:[ARG.4]
    00101036  |.  0BC0          OR EAX,EAX
    00101038  |.  75 18         JNZ SHORT 00101052
    0010103A  |.  8B4C24 14     MOV ECX,DWORD PTR SS:[ARG.3]
    0010103E  |.  8B4424 10     MOV EAX,DWORD PTR SS:[ARG.2]
    00101042  |.  33D2          XOR EDX,EDX
    00101044  |.  F7F1          DIV ECX
    00101046  |.  8BD8          MOV EBX,EAX
    00101048  |.  8B4424 0C     MOV EAX,DWORD PTR SS:[ARG.1]
    0010104C  |.  F7F1          DIV ECX
    0010104E  |.  8BD3          MOV EDX,EBX
    00101050  |.  EB 41         JMP SHORT 00101093
    00101052  |>  8BC8          MOV ECX,EAX
    00101054  |.  8B5C24 14     MOV EBX,DWORD PTR SS:[ARG.3]
    00101058  |.  8B5424 10     MOV EDX,DWORD PTR SS:[ARG.2]
    0010105C  |.  8B4424 0C     MOV EAX,DWORD PTR SS:[ARG.1]
    00101060  |>  D1E9          /SHR ECX,1
    00101062  |.  D1DB          |RCR EBX,1
    00101064  |.  D1EA          |SHR EDX,1
    00101066  |.  D1D8          |RCR EAX,1
    00101068  |.  0BC9          |OR ECX,ECX
    0010106A  |.^ 75 F4         \JNZ SHORT 00101060
    0010106C  |.  F7F3          DIV EBX
    0010106E  |.  8BF0          MOV ESI,EAX
    00101070  |.  F76424 18     MUL DWORD PTR SS:[ARG.4]
    00101074  |.  8BC8          MOV ECX,EAX
    00101076  |.  8B4424 14     MOV EAX,DWORD PTR SS:[ARG.3]
    0010107A  |.  F7E6          MUL ESI
    0010107C  |.  03D1          ADD EDX,ECX
    0010107E  |.  72 0E         JB SHORT 0010108E
    00101080  |.  3B5424 10     CMP EDX,DWORD PTR SS:[ARG.2]
    00101084  |.  77 08         JA SHORT 0010108E
    00101086  |.  72 07         JB SHORT 0010108F
    00101088  |.  3B4424 0C     CMP EAX,DWORD PTR SS:[ARG.1]
    0010108C  |.  76 01         JBE SHORT 0010108F
    0010108E  |>  4E            DEC ESI
    0010108F  |>  33D2          XOR EDX,EDX
    00101091  |.  8BC6          MOV EAX,ESI
    00101093  |>  5E            POP ESI
    00101094  |.  5B            POP EBX
    00101095  \.  C2 1000       RETN 10
    00101098      CC            INT3
    00101099      CC            INT3
    0010109A      CC            INT3
    0010109B      CC            INT3
    0010109C      CC            INT3
    0010109D      CC            INT3
    0010109E      CC            INT3
    0010109F      CC            INT3
    001010A0  /$  8B4424 08     MOV EAX,DWORD PTR SS:[ARG.2]             ; mul64._allmul(void)
    001010A4  |.  8B4C24 10     MOV ECX,DWORD PTR SS:[ARG.4]
    001010A8  |.  0BC8          OR ECX,EAX
    001010AA  |.  8B4C24 0C     MOV ECX,DWORD PTR SS:[ARG.3]
    001010AE  |.  75 09         JNZ SHORT 001010B9
    001010B0  |.  8B4424 04     MOV EAX,DWORD PTR SS:[ARG.1]
    001010B4  |.  F7E1          MUL ECX
    001010B6  |.  C2 1000       RETN 10
    001010B9  |>  53            PUSH EBX
    001010BA  |.  F7E1          MUL ECX
    001010BC  |.  8BD8          MOV EBX,EAX
    001010BE  |.  8B4424 08     MOV EAX,DWORD PTR SS:[ARG.1]
    001010C2  |.  F76424 14     MUL DWORD PTR SS:[ARG.4]
    001010C6  |.  03D8          ADD EBX,EAX
    001010C8  |.  8B4424 08     MOV EAX,DWORD PTR SS:[ARG.1]
    001010CC  |.  F7E1          MUL ECX
    001010CE  |.  03D3          ADD EDX,EBX
    001010D0  |.  5B            POP EBX
    001010D1  \.  C2 1000       RETN 10
    There is no floating point instructions but the result can be truncated unlike VB6.

  15. #15
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    6,585

    Re: CCur Function

    Quote Originally Posted by Niya View Post
    Not so fast. You guys are looking at it the wrong way. You have to think in terms of the right tool for the job. The Currency type is extremely bloated, true. The Decimal type might be even more slow. However, their purpose is not about performance, it's meant for stable financially calculations. Finances have a very low tolerance for rounding errors. I don't know about you guys but I can't see any application that deals with finance needing to perform intensive financial calculations in tight loops which is about the only way you would ever notice how dreadfully slow the Currency data type is.

    If you're modeling the whether in real time or writing a game engine then you need performance. You won't use data types like Currency for calculations in that domain. You may not even write such code yourself, you would use things like CUDA or DirectX.

    It's not about VB6 being old in this case because I'll tell you right now, .Net's Decimal type is even slower than Currency because all of it is implemented in managed code which means ultimately the disassembly would be even more bloated than what you see for the Currency type. I was also surprised to find that the .Net compiler as of Visual Studio 2013 still compiles floating point code to x87 FPU instructions instead of SSE. I don't know if this has changed with Visual Studio 2019. The thing is, it doesn't matter because the truth is, we really do not need bleeding edge performance 99% of the time. Decent performance is enough for most of the code we write so there is no need for them to be super optimized. One of the bad habits programmers tend to pick up at one point or another is believing we need to optimize everything all the time. We don't. If a piece of un-optimized code doesn't degrade the user experience, then the code is perfectly fine the way it is.
    Niya, yeah, I basically agree with you, and I wasn't really complaining. I was just trying to point out that, if VB6's compiler (both p-code and binary) were written from scratch today (even if only as 32-bit things), they'd be much more optimized than they are. I mean, what the heck does "Favor Pentium Pro" mean? Or, what's the difference between "Optimize for Fast Code" vs "Optimize for Small Code". By today's standards, I doubt the differences there actually mean much of anything. However, if we were to consider similar questions today, they'd read very differently, possibly providing a great deal more optimization than the VB6 we have will ever achieve.

    But again, I'm not complaining. I'll most-likely die thinking that the VB6 IDE is one of the most RAD and streamlined IDEs out there, but that also has a great deal to do with my rather deep familiarity with the language.

    Take Care,
    Elroy
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  16. #16
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    6,021

    Re: CCur Function

    Quote Originally Posted by Elroy View Post
    I mean, what the heck does "Favor Pentium Pro" mean? Or, what's the difference between "Optimize for Fast Code" vs "Optimize for Small Code".
    Oh yea lol. The Pentium Pro is a dinosaur and I don't think anybody in 2020 cares about optimizing for small code.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  17. #17
    Addicted Member
    Join Date
    Jun 2019
    Posts
    232

    Re: CCur Function

    If someone is interested, here is interesting video about performance in JIT compiled code and how it can be optimized with new CPUs:

    * Disclaimer: this is about Java, but it can be applied to any modern JIT compiler


    The code example starts at 16:00m where simple loop is compiled with old and new CPU features - AVX, AVX2, AVX512...

    Now compare with the "optimized" code generated by VB6 and check what year it is, what CPU you have and what will be the differences with non-optimized slow byte code.

    There are more optimization tricks in the new JIT compilers which can make byte code to work much faster compared with old binary code.

    Just few thoughts on performance, VB6, .NET, binary vs byte code.

  18. #18
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    6,021

    Re: CCur Function

    Quote Originally Posted by peterst View Post
    The code example starts at 16:00m where simple loop is compiled with old and new CPU features - AVX, AVX2, AVX512...

    Now compare with the "optimized" code generated by VB6 and check what year it is, what CPU you have and what will be the differences with non-optimized slow byte code.

    There are more optimization tricks in the new JIT compilers which can make byte code to work much faster compared with old binary code.

    Just few thoughts on performance, VB6, .NET, binary vs byte code.
    Unfortunately Microsoft is a quite lax in this area. Microsoft's .Net JIT still does things the old fashion way. It's not as advanced as that JIT showcased in that video. As a test, I wrote the exact same program shown at 16 minutes into the video:-
    vbnet Code:
    1. '
    2.     Private Function sumLoop(ByVal a As Integer()) As Integer
    3.         Dim sum As Integer
    4.  
    5.         For i = 0 To a.Length - 1
    6.             sum += a(i)
    7.         Next
    8.         Return sum
    9.     End Function

    The .Net JIT produced this code for the loop:-
    asm Code:
    1. '
    2. For i = 0 To a.Length - 1
    3.  
    4.  mov         eax,dword ptr [ebp-40h]  
    5.  mov         eax,dword ptr [eax+4]  
    6.  mov         edx,1  
    7.  sub         eax,edx  
    8.  jno         026020A6  
    9.  call        7522ED00  
    10.  mov         dword ptr [ebp-4Ch],eax  
    11.  xor         edx,edx  
    12.  mov         dword ptr [ebp-50h],edx  
    13.  nop  
    14.  jmp         026020DA  
    15.  
    16.  sum += a(i)
    17.  
    18.  mov         eax,dword ptr [ebp-50h]  
    19.  mov         edx,dword ptr [ebp-40h]  
    20.  cmp         eax,dword ptr [edx+4]  
    21.  jb          026020C1  
    22.  call        7522E950  
    23.  mov         eax,dword ptr [edx+eax*4+8]  
    24.  add         dword ptr [ebp-48h],eax  
    25.  jno         026020CF  
    26.  call        7522ED00  
    27.  
    28.  Next

    As you can see, the .Net JIT didn't perform the vectorization done by the JIT in the video. It compiled plain old school x86 code. Nothing fancy. No SSE, no MMX, nothing.

    It's not a deal breaker for me but it does show how slow MS is to evolve sometimes.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  19. #19
    Addicted Member
    Join Date
    Jun 2019
    Posts
    232

    Re: CCur Function

    What I've found on StackOverflow is that during debugging JIT optimizations are not applied. Real performance improvements are when you build in Release mode and run the application outside Visual Studio.

    Even in .NET 5 (as currently version) the JIT compiler maybe is not as optimized as the Java one in the video (which is mostly suitable for server loads), but many developers wrote or had shown results with amazing performance improvement by just migrating from .NET Framework ASP.NET to .NET Core ASP.NET.

    For new VB6 replacement is important to choose the right compile mode - to native code or byte code, and choose the proper JIT runtime which is constantly developed and improved so even old code will have improved performance with new runtime version.

    Currency or Decimal types can become part of the new CPUs and with proper JIT compilation to gain better performance.

  20. #20
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    6,021

    Re: CCur Function

    Quote Originally Posted by peterst View Post
    and choose the proper JIT runtime which is constantly developed and improved so even old code will have improved performance with new runtime version.
    This is the biggest selling point for a JIT over static compilation in my opinion.

    Quote Originally Posted by peterst View Post
    Currency or Decimal types can become part of the new CPUs and with proper JIT compilation to gain better performance.
    It's unlikely in this case and I'll explain why. The best possible case is that some future CPU implements a Decimal type, perhaps in the form of something like the x87 FPU. Now compilers would be able to use Decimals in the same manner that it would with classic numeric data types. The problem is that the Decimal type in .Net is actually a completely managed implementation. If the JIT were to suddenly replace all uses of the Decimal type with pure assembly, this could break applications when they try to call Decimal's methods and they don't exist on account of the JIT optimizing them away.

    Besides, I don't think there is any sensible reason to want to optimize the Decimal type. Slow as it is, it fulfills its purpose quite acceptably.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena


    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. -jmcilhinney

  21. #21

    Thread Starter
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    9,988

    Re: CCur Function

    This thread kind of spiraled out of control, but my original restatement (post 3) of Dil's post is more or less correct.

    Just a reminder, I am rewriting a VB6 application (originally written VB3 and upgraded until VB6) to a C#/Angular application. I just needed to know if there was any nuances associated with the function that I needed to know about.

    I'll go ahead and mark this thread as resolved.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width