They really run into interesting problem here. Should they treat the inode as a string (since it's not likely anyone would do mathematical operation on it), use a two field uint32 array (for correctness) or hash into a 53 bit value (which can't be reversed into the existing windows API). Hard one. +1 for the uint32 array field which I think makes the most sense.
I'm not sure an array matches the use case of an inode number. The only practical uses are comparison and indexing. It is more natural to use strings to index hashes than a typed arrays.
Some were concerned with the performance of comparing strings, because a hex encoded string has 16 values to compare instead of 2. One might think this results in a 700% slowdown, but assuming that the operation short circuits, it is theoretically a 6.67% slowdown [0].
Edit: Benchmarks [1] indicate that string comparisons are significantly faster. It is not surprising that string comparison has been heavily optimized.
I think I prefer the string option. inodes (including Windows 64-bit file IDs) are opaque values. All you can do is compare them with one another and pass them to functions that accept inodes. Interpreting the integer value of the inode is meaningless. Using a string preserves these semantics, but using an array of numbers could be confusing/annoying because it breaks comparison with == and ===. Also, using a string would be forwards-compatible with any future changes to how Windows or Node identifies files, for example, Windows 8 has a 128-bit file ID type (which is needed for ReFS, I think.)
I've done the high/lo "struct" split for pointers in Flash when porting from 32-bit to 64-bit, and it was a pain in the ass (in part because of the ==/=== behavior with arrays you point out). In retrospect I should've gone with strings. I think we may have even eliminated the pointers before shipping anything, and wouldn't have been a significant perf hit even if we hadn't. (For all I know, it might've even been a perf gain...)
As parent mentions, comparison with ==/=== are "broken" for arrays or classes. Or more accurately, they now do reference comparisons instead of value comparisons. This means you have to replace a lot of this (using Flash/ActionScript as the example here):
function updateIcon(id: int, ...) {
for (var icon in icons) {
if (icon.id === id) {
...
}
}
}
With, say, something like this:
function updateIcon(id: Ptr, ...) {
for (var icon in icons) {
if (Ptr.compare(icon.id, id) === 0) {
...
}
}
}
Or:
function updateIcon(id: Array, ...) {
for (var icon in icons) {
if (ObjectUtil.compare(icon.id, id) === 0) {
...
}
}
}
Assuming you want to preserve the exact semantics of the existing code. If you miss a single comparison, your code will still compile. You will get no runtime exceptions, because == and === are still legal. It'll just have a subtle runtime flaw that will only manifest itself if two interop sites construct the same pointer value as different Ptr or array instances without interning (read: caching/leaking Ptr or array instances, which has it's own problems.) You cannot override == or === to do the right thing (tm) either.
In the unlikely event you do a large refactoring or conversion completely flawlessly, your coworker's muscle memory will, rather understandably, still end up causing problems.
function updateIcon(id: String, ...) {
for (var icon in icons) {
if (icon.id === id) {
...
}
}
}
This is less refactoring, and just works(tm), because String ==/=== already compares the value of the strings. No muscle memory to update, easier to print in debug and trace statements, etc...
It's worth pointing out that (3) sounds good, but it's an imperfect solution too. If Number.isNaN(num) is true, num === num will be false. Not just one, but several 64-bit patterns are considered NaN when represented as a floating-point number, so if all possible 64-bit values can be used, this could cause the opposite problem where inodes that are actually the same are considered not equal by JavaScript.
9 comments
[ 4.0 ms ] story [ 30.3 ms ] threadSome were concerned with the performance of comparing strings, because a hex encoded string has 16 values to compare instead of 2. One might think this results in a 700% slowdown, but assuming that the operation short circuits, it is theoretically a 6.67% slowdown [0].
[0]: http://wolfr.am/l1JVtEi7
Edit: Benchmarks [1] indicate that string comparisons are significantly faster. It is not surprising that string comparison has been heavily optimized.
[1]: https://jsperf.com/64bit-comparison
In the unlikely event you do a large refactoring or conversion completely flawlessly, your coworker's muscle memory will, rather understandably, still end up causing problems.
This is less refactoring, and just works(tm), because String ==/=== already compares the value of the strings. No muscle memory to update, easier to print in debug and trace statements, etc...They could (1) make a two element UInt32Array or (2) use strings or (3) use all 64 bits of the floating point JS number type.