Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

If this were C, I would guess that Roland's solution would probably be faster, since it does not involve a conditional branch (and conditional branches can be expensive when they are not properly predictedconditional branches can be expensive when they are not properly predicted). However, since this is VB, I suspect that my code will be slightly faster, mainly because string operations are so incredibly expensive that it is worth a mispredicted branch penalty to elide one if at all possible. And, if I may compliment myself, I'd say that my solution is slightly more readable from a code-review perspective. (But either solution would require explicit comments describing the rationale.)

Creating debug info is just a good idea, in case you ever have to debug your applicationCreating debug info is just a good idea, in case you ever have to debug your application, and it is impossible to generate it later. This is arguably less useful for a strictly VB programmer who wouldn't know how to use another debugger with a gun to his head, but it is a skill that is truly worth learning, and if you ever have to call in an expert, a PDB file is invaluable. It doesn't hurt anything to generate it and ignore it.

If this were C, I would guess that Roland's solution would probably be faster, since it does not involve a conditional branch (and conditional branches can be expensive when they are not properly predicted). However, since this is VB, I suspect that my code will be slightly faster, mainly because string operations are so incredibly expensive that it is worth a mispredicted branch penalty to elide one if at all possible. And, if I may compliment myself, I'd say that my solution is slightly more readable from a code-review perspective. (But either solution would require explicit comments describing the rationale.)

Creating debug info is just a good idea, in case you ever have to debug your application, and it is impossible to generate it later. This is arguably less useful for a strictly VB programmer who wouldn't know how to use another debugger with a gun to his head, but it is a skill that is truly worth learning, and if you ever have to call in an expert, a PDB file is invaluable. It doesn't hurt anything to generate it and ignore it.

If this were C, I would guess that Roland's solution would probably be faster, since it does not involve a conditional branch (and conditional branches can be expensive when they are not properly predicted). However, since this is VB, I suspect that my code will be slightly faster, mainly because string operations are so incredibly expensive that it is worth a mispredicted branch penalty to elide one if at all possible. And, if I may compliment myself, I'd say that my solution is slightly more readable from a code-review perspective. (But either solution would require explicit comments describing the rationale.)

Creating debug info is just a good idea, in case you ever have to debug your application, and it is impossible to generate it later. This is arguably less useful for a strictly VB programmer who wouldn't know how to use another debugger with a gun to his head, but it is a skill that is truly worth learning, and if you ever have to call in an expert, a PDB file is invaluable. It doesn't hurt anything to generate it and ignore it.

replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link

Now, I notice that you did correctly force the use of the string-based Right function by using the $ type suffix, which is a standard trick to ensure as optimal code as possible. This is good. You didn't do the same thing for Hex. Personally, I have no idea whether it is actually necessary or not—is there a variant-based version of Hex? Maybe, I don't know. And I don't want to have to worry about it when I write or review code, so I always use the $ type suffix when I am working with strings. I suggest that you do the same. (Mat's Mug says Hex does have a variant versionMat's Mug says Hex does have a variant version, so looks like this is sage advice after all!)

Comintern made one attempt alreadyComintern made one attempt already, and it is interesting to study. Immediately one problem jumps out—it does not produce correct results. Specifically, the order of the red and blue component values are reversed, such that instead of AABBCC, his code gives CCBBAA. On little-endian architectures, like the x86, integer values are stored in memory with the least-significant byte at the smallest address. This means that "RGB" colors are actually represented in memory using an BBGGRR format, whereas you are wanting the standard, web-style RRGGBB format for your hexadecimal output. This is a minor bug, though, and should be fixable.

How? By using bit-manipulation tricks to do the byte-swapping. Basically, you do what you would have done in C (or at least, what I would have done in C, maybe you're a real VB programmer and don't think in the language of blasphemy). This is basically what Roland Illig did in his codeRoland Illig did in his code. You start with the input value, in AABBGGRR format. Then, you isolate each of the individual color components (except the alpha channel, which we don't care about):

Now, I notice that you did correctly force the use of the string-based Right function by using the $ type suffix, which is a standard trick to ensure as optimal code as possible. This is good. You didn't do the same thing for Hex. Personally, I have no idea whether it is actually necessary or not—is there a variant-based version of Hex? Maybe, I don't know. And I don't want to have to worry about it when I write or review code, so I always use the $ type suffix when I am working with strings. I suggest that you do the same. (Mat's Mug says Hex does have a variant version, so looks like this is sage advice after all!)

Comintern made one attempt already, and it is interesting to study. Immediately one problem jumps out—it does not produce correct results. Specifically, the order of the red and blue component values are reversed, such that instead of AABBCC, his code gives CCBBAA. On little-endian architectures, like the x86, integer values are stored in memory with the least-significant byte at the smallest address. This means that "RGB" colors are actually represented in memory using an BBGGRR format, whereas you are wanting the standard, web-style RRGGBB format for your hexadecimal output. This is a minor bug, though, and should be fixable.

How? By using bit-manipulation tricks to do the byte-swapping. Basically, you do what you would have done in C (or at least, what I would have done in C, maybe you're a real VB programmer and don't think in the language of blasphemy). This is basically what Roland Illig did in his code. You start with the input value, in AABBGGRR format. Then, you isolate each of the individual color components (except the alpha channel, which we don't care about):

Now, I notice that you did correctly force the use of the string-based Right function by using the $ type suffix, which is a standard trick to ensure as optimal code as possible. This is good. You didn't do the same thing for Hex. Personally, I have no idea whether it is actually necessary or not—is there a variant-based version of Hex? Maybe, I don't know. And I don't want to have to worry about it when I write or review code, so I always use the $ type suffix when I am working with strings. I suggest that you do the same. (Mat's Mug says Hex does have a variant version, so looks like this is sage advice after all!)

Comintern made one attempt already, and it is interesting to study. Immediately one problem jumps out—it does not produce correct results. Specifically, the order of the red and blue component values are reversed, such that instead of AABBCC, his code gives CCBBAA. On little-endian architectures, like the x86, integer values are stored in memory with the least-significant byte at the smallest address. This means that "RGB" colors are actually represented in memory using an BBGGRR format, whereas you are wanting the standard, web-style RRGGBB format for your hexadecimal output. This is a minor bug, though, and should be fixable.

How? By using bit-manipulation tricks to do the byte-swapping. Basically, you do what you would have done in C (or at least, what I would have done in C, maybe you're a real VB programmer and don't think in the language of blasphemy). This is basically what Roland Illig did in his code. You start with the input value, in AABBGGRR format. Then, you isolate each of the individual color components (except the alpha channel, which we don't care about):

added 79 characters in body
Source Link
Cody Gray
  • 4.6k
  • 19
  • 30
  1. Explicitly pass input parameters by value. This should have been the default, but it wasn't in classic COM-based VB, so you need to write it out. ByRef is actually a perverse choice for the default, since it is almost never what you want. It is certainly not what you want for primitive types like Long. (But it probably is what you want for strings, unless passing them out-of-process, e.g. in a COM server.)

  2. As others have pointed out, l is a rather poor choice for a parameter name. Roland says one problem with it is that it can be difficult to distinguish from the digit 1 or a capital I. I'd say that's more a reflection on your choice of a font for your editor, but this is still a valid concern. My major issue with it is that it looks like a lame attempt at AppsSystems Hungarian notation. I know this used to be all the rage in VB programming, but that was mostly cargo-cult. Unless you're using variants (and you probably shouldn't be) the language is sufficiently strongly-typed that embedding type information in the name of the variable serves little point. The only type prefixes I allow myself are for names of controls (mostly because it makes finding them in IntelliSense significantly easier; I always remember the type of control much more readily than I remember its name) and "member" prefixes (e.g., m_). Aside from that, the only prefixes you should be using are meaningful semantic ones, in the Systems Hungarian veinin the Apps Hungarian vein.

  1. Explicitly pass input parameters by value. This should have been the default, but it wasn't in classic COM-based VB, so you need to write it out. ByRef is actually a perverse choice for the default, since it is almost never what you want. It is certainly not what you want for primitive types like Long. (But it probably is what you want for strings, unless passing them out-of-process, e.g. in a COM server.)

  2. As others have pointed out, l is a rather poor choice for a parameter name. Roland says one problem with it is that it can be difficult to distinguish from the digit 1 or a capital I. I'd say that's more a reflection on your choice of a font for your editor, but this is still a valid concern. My major issue with it is that it looks like a lame attempt at Apps Hungarian notation. I know this used to be all the rage in VB programming, but that was mostly cargo-cult. Unless you're using variants (and you probably shouldn't be) the language is sufficiently strongly-typed that embedding type information in the name of the variable serves little point. The only type prefixes I allow myself are for names of controls (mostly because it makes finding them in IntelliSense significantly easier; I always remember the type of control much more readily than I remember its name) and "member" prefixes (e.g., m_). Aside from that, the only prefixes you should be using are meaningful semantic ones, in the Systems Hungarian vein.

  1. Explicitly pass input parameters by value. This should have been the default, but it wasn't in classic COM-based VB, so you need to write it out. ByRef is actually a perverse choice for the default, since it is almost never what you want. It is certainly not what you want for primitive types like Long. (But it probably is what you want for strings, unless passing them out-of-process, e.g. in a COM server.)

  2. As others have pointed out, l is a rather poor choice for a parameter name. Roland says one problem with it is that it can be difficult to distinguish from the digit 1 or a capital I. I'd say that's more a reflection on your choice of a font for your editor, but this is still a valid concern. My major issue with it is that it looks like a lame attempt at Systems Hungarian notation. I know this used to be all the rage in VB programming, but that was mostly cargo-cult. Unless you're using variants (and you probably shouldn't be) the language is sufficiently strongly-typed that embedding type information in the name of the variable serves little point. The only type prefixes I allow myself are for names of controls (mostly because it makes finding them in IntelliSense significantly easier; I always remember the type of control much more readily than I remember its name) and "member" prefixes (e.g., m_). Aside from that, the only prefixes you should be using are meaningful semantic ones, in the Apps Hungarian vein.

Bounty Ended with 500 reputation awarded by Mathieu Guindon
remove C-style "0x" notation; add annotated disassembly (off-site link because this answer is too long already and this is only supplemental)
Source Link
Cody Gray
  • 4.6k
  • 19
  • 30
Loading
added 185 characters in body
Source Link
Cody Gray
  • 4.6k
  • 19
  • 30
Loading
Source Link
Cody Gray
  • 4.6k
  • 19
  • 30
Loading