16 ms·
What algorithm did Windows XP use to choose your initial user picture?
- ang_cire 7d agoMy eyes glazed over when I saw "recursively", and I had to re-read the last couple paragraphs again to grok it, and it's very cool.
- jasonvorhe 7d agoA couple of screenshots would've been useful for the post-millennial generations that never got to see the "beauty" (cough) of XP.
- moritzwarhier 7d agoHere's a blog post from 2003 with beautiful pictures. https://jakeludington.com/2003/12/17/create_your_own_windows_xp_user_account_pictures/ https://jakeludington.com/2003/12/17/create_your_own_windows...
- seba_dos1 7d agoThese pictures are so compressed they depict color rasterization artifacts more than the Luna UI style.
- CalRobert 7d agoI thought it looked great :-/
- Maken 7d agoXP is Microsoft's prettiest OS by far.
- mrweasel 7d agoThat's a matter of taste, but for many it was the Windows they used first and/or spend the most time on and there's a lot of love for that reason alone. I never used XP all that much, but I always changed the theme to the Windows 2000 look. I really didn't like the default, it looked unprofessional and clunky in my eyes. Upon release XP was also pretty universally mocked as a Fisher Price-like UI. To me Windows 95/NT 4 is still the gold standard in Windows UI. It's certainly not the prettiest, that would be Windows 2000, but it was easy to use, easy to navigate and efficient with space.
- TazeTSchnitzel 7d agoThe "Windows Classic" look on XP is exceptionally ugly, because those 3D-rendered icons just do not belong on a Windows 2000-style grey background for menus or buttons. (I have recently had to test both these OSes in VMs…)
- mrweasel 7d agoThat is true, it looked completely off, as if no one really bothered to tests it and make it look nice. It got rid of the horrible window decoration of the default theme, but the start menu looked terrible.
- Maken 7d agoThe first Windows I used was 98, and I sure didn't miss the blocky grey menus nor the pixelated icons. Maybe it was Fisher Price-ish but the new rounded buttons and borders were way more appealing to me.
- afzalive 7d agoTook me years to like Windows XP. Hated the new start menu. I always kept installing Windows 2000 (or ME, probably because it could use Windows 98 drivers but look like Windows 2000). I eventually got used to it and ended up liking it.
- deleted 6d ago[deleted]
- stingraycharles 7d agoIt was at this moment I realized that people are talking about liking the non-classic-look XP. I always immediately put things in classic look, no grouped windows, etc.
- alex_suzuki 7d agoIIRC correctly, XP’s stability greatly increased after Service Pack 2 was published.
- sunaookami 7d agoYou mean 7 ;)
- Maken 7d agoWindows 7 fixed Vista a bit, but the Aero windows were never pretty and the non-Aero decorations were painfully obvious a placeholder.
- sunaookami 7d agoAero was pretty though.
- medwards666 7d agoWindows 7 was certainly pretty, but I still think that W2000 was peak Windows UI (and I've been around since Windows 2.0)
- YPPH 7d agoI found each of 2000, XP, and 7 to be excellent in its own unique way. I'd be happy with any of them. But it also felt exciting to upgrade. It's all been downhill from there as far as UX goes.
- amiga-workbench 7d agoPerhaps with the Zune theme installed.
- delta_p_delta_x 7d agoI feel Vista was by far the best. 7 simplified it a bit, but that Start orb and black taskbar on Vista, man, that was glorious.
- kasabali 7d agoIMO Aero parts looked phenomenal but older Win32 parts like toolbars etc. didn't fit and looked odd
- meerita 7d agoEhem... nothing beats the beauty and simplicity of Win 95 :)
- edoceo 7d agoDidn't that design appear first in 3.51?
- TheAmazingRace 7d agoOnly if you install the Shell Technology Preview from Microsoft. NT 3.51 came with the classic Win 3.x look and feel as well as Program Manager.
- edoceo 7d agoYea, it was 4.0, oops
- fractal618 7d agoI like the installation music :-)
- rzzzt 7d ago"Welcome to Windows 98" with the church bell and sick bass intro can never be beaten. It's cut short unfortunately.
- bsoqk 7d agohttps://devblogs.microsoft.com/oldnewthing/20040331-00/?p=39953 https://devblogs.microsoft.com/oldnewthing/20040331-00/?p=39... >During the Luna studies, that people’s reaction to Luna was often, “Wow this would be a great UI for X,” where X was “my dad” or “my employees” or “my daughter”. People didn’t look at it as the UI for themselves; rather, they thought it was a great UI for somebody else. (Luna is the name of the default look of Windows XP)
- ksncksndsh 7d agoThat’s Vista. And there’s no contest whatsoever. They’ve never been able to again achieve the perfect balance of elegance and functionality that Vista’s UI had. Its Vista. Like it or hate it. It’s Vista
- PalmPilotProMax 7d agoI don't see how that's relevant? Article is about the RNG implementation, it doesn't matter what the profile pictures are.
- lirolero 7d ago> I don't see how that's relevant? nobody cares
- bhaney 7d ago100 seems like a very unnecessarily low limit, even for the time
- daveoc64 7d agoIt's well above the number of images that were in the applicable folder by default, so seems pretty appropriate to me.
- moritzwarhier 7d agoSome say the Admin account defaulted to a chessboard. I think it's true, but not sure if I'm just falling victim to false memories... help?
- abhinavk 7d agoI remember it like that too. Or is it Mandela effect?
- NitpickLawyer 7d agoThe Magnus effect? :)
- bombcar 7d agoIt might be that the randomization code was bypassed in some cases - like creating an account in safe boot mode or similar.
- bhaney 7d agoThere's no way my memory of this is reliable anymore, but I also remember my administrator account being chess pieces (and my user account being an orange fish).
- xx_ns 7d agoIt makes sense. The chess piece is the first profile picture in the list.
- TazeTSchnitzel 7d agoThe account named "Administrator" that Windows created for you always had the chess piece.
- cgio 7d agoThe times when people spent an extra brain cycle to avoid billions of second passes.
- bombcar 7d agoDoes it also check existing users so you don't match one?
- reddalo 7d agoIt doesn't: https://github.com/tongzx/nt5src/blob/daad8a087a4e75422ec96b7911f1df4669989611/Source/XPSP1/NT/shell/shell32/userpict.cpp#L458 https://github.com/tongzx/nt5src/blob/daad8a087a4e75422ec96b...
- mawadev 7d agoThat is a case I only become aware of when I read blogs like this. Technically I could solve it the same way, but these days you have so many tasks on your desk, you don't think about the problem and implications at all and that awareness/discipline is drowned in the noise/unlearned over time. If someone only gave me 2 minutes for this, because they think it is very simple (as always), I'd have done a count of files of a specific pattern in the directory and then picked a random index, very naive and quick and dirty programming, no sampling at all, just to avoid discussions why it takes so long with people who don't want to hear it. This reminds me of when I did a lot of C#, Java, JS, Python in my life, filling maps of strings and objects until I started with zig and noticed how expensive and complicated strings and data structure allocations can be. It kind of blew my mind how much memory and computation we waste when we try to get stuff done as fast as possible because of budget/time constraints.
- cabirum 7d agoCounterexample: desktop icon layout in quadratic time: https://randomascii.wordpress.com/2021/02/16/arranging-invisible-icons-in-quadratic-time/ https://randomascii.wordpress.com/2021/02/16/arranging-invis... Its not like windows is the pinnacle of software craftsmanship.
- kevin_thibedeau 7d agoI'd bet this bug also shows up in Vista file explorer with auto arrange disabled. Nobody will ever need more than 100 icons on their 800x600 workstation. Ship it.
- Aurornis 7d agoTwo things that have helped me with quickly recognizing these situations: Programming for MCUs. Less so today when multi-hundred MHz MCUs are cheap, but even several years ago there were a lot of products where you needed to use the cheapest MCU and everything it did had to be optimized to avoid stalls and edge cases. Second is doing LeetCode problems for fun/practice. This will elicit a groan from a lot of people, but the algorithms and pathological edge cases you learn really do change your thinking. The most interesting ones are the hard problems where they’ve added some hidden test case that causes naive solutions and algorithms to blow up. You start thinking on high alert for edge cases and Big O problems. It’s more fun when you’re doing it to learn on your own than for forced interview prep.
- lyorig 7d agoMan, every post from Raymond Chen regarding Windows internals is like a little Xmas. I wonder whether he has to ask someone for permission before publishing this knowledge, though.
- alex_suzuki 7d agoI also wonder what his thoughts on “modern Windows” are
- dyllon 7d agoHis silence speaks a thousand words.
- bigstrat2003 7d agoYeah I agree. Mr. Chen strikes me as too professional to put his employer on blast like that, but he's likely not a fan.
- jasomill 6d agoI imagine he's fine with it in terms of job satisfaction at the very least, as far as I can tell his areas of expertise are shell and related COM internals, and he clearly takes pride in the nuances of cleaning up other peoples' messes, and if there are two things that have remained constant in Windows programming over the past 30 years, it's COM and messes.
- darig 7d ago[dead]
- 98codes 7d agoIt's not as if he's stopped working on Windows since 2000.
- Hydraulix989 7d agoEasier for a guy like him to be forgiven than to ask permission. Being tenured and one of the top engineers in your company with a very proven track record gives you quite a bit more freedom.
- KellyCriterion 7d agoWhy they made it that complex? A simple rand/mod based on first character of username should be sufficient?
- lentil_soup 7d agobecause you don't know the number of images before running the code so no number to do the mod part
- moffkalast 7d agoWhy wouldn't you know that? It's a set of preloaded stock photos, it's always gonna be the same number.
- consp 7d agoAt compile time of when the pr department decided to change it?
- herywort 7d ago> As a final safety check, the code stops after sampling 100 pictures. This avoids pathological behavior if somebody puts a million files in the Default Pictures directory
- bombcar 7d agoIt’s a directory. You could add pictures to it, and we did in our image layout (mainly for fun, but they wanted the logo as one).
- elgertam 7d agoOn initial install, sure. But user accounts can also be created at arbitrary times. The user may have changed the set of photos in the intervening time and might even be editing the directory during profile creation.
- throwaway219450 7d ago
- EMIRELADERO 7d agoFor those interested, here's the actual code Chen talks about: https://github.com/tongzx/nt5src/blob/daad8a087a4e75422ec96b7911f1df4669989611/Source/XPSP1/NT/shell/shell32/userpict.cpp#L458 https://github.com/tongzx/nt5src/blob/daad8a087a4e75422ec96b...
- ycuser2 7d agoDidn't know that NT5 source is available for the public. Why Microsoft does not ban/delete it on GitHub?
- lr0 7d agoThey are usually deleted, maybe this one hasn't got popular enough yet.
- Philpax 7d agoIt's been around for six years; at this point, I imagine any damage it could have done has been done already.
- sph 7d agoIt'll pop up elsewhere so might as well keep it online on their servers. And it's an old version of the OS anyway. If it were the Windows 11 source, it'd get nuked immediately
- VCFundedGenYer 7d ago> And it's an old version of the OS anyway. Most modern Windows code was written in 1995. Don't assume for one moment that it isn't in production Win11 today.
- kevin_thibedeau 7d agoYou can still get windows 3 directory picker dialogs in obscure places like the ODBC data source utility.
- impoppy 7d ago>Raymond has been involved in the evolution of Windows for more than 30 years. He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.
- carrja99 7d agoThat made me chuckle too. No utility, but I did find it interesting.
- VCFundedGenYer 7d agoA true Microsoft drone to the end.
- ape4 7d agoIt's somewhat odd that filesystems don't have a call to tell you how many files are in a folder.
- conorcleary 7d agojust have it count how many times del cmd runs successfully /s
- eventualcomp 7d agoI feel like there would either be too many locks or too much contention on something like /var/log or /tmp if that API was ever exposed to userspace.
- ygra 7d agoEither that call would have to do the same (i.e., walking the files and counting), or you'd need some additional metadata in the directory entry to store how many files there are, requiring additional storage accesses for adding and removing files. Adding to that that both FAT32 and NTFS are quite old and had to run on older hardware. Cycles and disk accesses are not free. On top of that, how often is it necessary to efficiently know the number of files in a directory while at the same time not caring about the files enough to list or display them? This algorithm is a special case where you could use the count of using a bit simpler code that ultimately would have the same file system API calls (since you cannot tell the FS to give you file #37 from that directory, so you'd have to use FindNextFile 37 times anyway, just like the sampling algorithm).
- vishnuaniyan 7d ago[dead]
- dsego 7d agoWhy doesn't it return on the first match?
- quentinkent1 7d agoexactly. There is something wrong with the code snippet.
- arpadav 7d agoNo there is not. First element is defacto winner, but you still have to loop through the rest with 1/n chance of being selected to fully give each element a chance of winner selection
- fschuett 7d agoYeah I think the "wrong feeling" is just that this could, in theory, be O(1) with something like: pics[Math.random() * len(pics)] ... assuming that random() gives you a number from 0..1 - but that's why it feels "wrong".
- akdev1l 7d agolen(pics) either already knows about the length or it needs to count so it’s O(n)
- Anon_troll 7d agoThe len(pics) can be O(n), especially if iterators are used like here. Also, an O(1) lookup would require a previous O(n) pass over the data anyway. The picture selection algorithm's kind of single-pass iterator usage might have been more performant back in the XP days, as it avoids possibly expensive operations. Modern CPU/other optimizations might make a multi-pass approach more performant due to better memory locality or other factors.
- kleiba2 7d agoOn count == 1, the winner gets set to the first element, true. But the function does not return yet! So the value might get overwritten during the remainder of the for-loop.
- deleted 7d ago[deleted]
- Aditya_0315 7d agoWhat is amazing is the amount of consideration given to an issue which would escape the majority of users. It is surprising how complex an apparently easy process turns out when considering certain special cases.
- frou_dh 7d agoI'm disappointed that it is not influenced by the username ... "You sound like a skateboard kinda person"
- bayindirh 7d agoHonestly, I don't understand Microsoft. These guys solve the most mundane problems with most elegant solutions and with sound edge-case handling scenarios, then they destroy all the effort with subpar programming where it matters and with user hostile behavior where they can't botch it.
- airstrike 7d agoThey're a very large organization with engineers of widely varying skills in projects with very different timelines. I get what you mean, but it's really hard for any organization this size to drive consistent quality across the board.
- waz0wski 7d ago> // Assume everything in the dir is a vaild image file Yep.. And image files were, and continue to be, a huge exploit attack vector
- bayindirh 7d agoWe had bigger problems back then, and the function ran considerably rarely when compared the other parts of the OS, so it was a valid assumption at that age. However, I still remember Wine laughing at Windows for WMF exploit and end up being affected from the same exploit. Now, that was a good laugh.
- amelius 7d agoThey simply find some problems more interesting to solve than others. Just like the rest of us.
- amelius 7d ago(Perhaps it shows that Apple engineers are pushed to grind at the boring problems more; therefore maybe it is better to work at Microsoft)
- 7d ago
- scrumper 7d agoThis is a fun example of the cognitive switch you have to employ when first starting to program a computer. It's extremely easy for a human to pick at random one thing from a pile of things: you reach out your hand and grab it, maybe swirling them around on the table first to shuffle the order. For a computer, there's no direct analogy to that. They just can't do it. And the human process is nothing even slightly like the one the computer follows: we don't have to count the sets and iterate over them, or count the items and then generate a random number to pick the nth item, or risk picking a null item.
- rhplus 7d agoI think this article highlights more the importance of understanding system limits in the 1990s versus today. No-one would care to much today if the code review for this feature had “files.count()” or whatever in it, but in the mid 90s that would have been a huge performance red flag because a user would literally hear their hard drive clicking away and see the blinkenlights.
- layer8 7d agoThe problem isn’t counting the files (the algorithm in the article also counts the files), but that if you determine that you want to use the ith file only after counting all files, you have to iterate over the whole directory again (or over expected half of it) to find that file.
- madibo3156 7d agoThe mechanism is interesting, but I'm not fully understanding the importance. We say it was done this way because a user would appreciate the speedup. The difference is one traversal versus expected one and one-half traversals. How slow was this traversal at the time for this difference to be significant?
- layer8 7d agoIt will depend on details like file system fragmentation (Windows XP could run on FAT32), but it could conceivably make a perceptible difference on a slow HDD when there are many pictures in the directory. You also have to check more error cases, for when the second iteration fails for some reason. The mindset was probably "why complicate the code with multiple iterations and make it less efficient?" when the efficient solution is straightforward and arguably simpler.
- ulrikrasmussen 7d agoBut the naive way of doing this also wouldn't really require two passes, right? It would just require more memory because you would first save all file names in an array (stopping at 100), then pick a random one in constant time.
- wongarsu 7d agoHow do you know how big your array has to be in a single pass? I don't think the WinXP source uses vectors or similarly ergonomic auto-growing arrays. You could preallocate an array big enough for 100 paths of length MAX_PATH, but that's a bit wasteful. And it doesn't sound like you'd actually end up with fewer lines of code (in that flavor of C++, in python it would be different)
- ulrikrasmussen 7d agoYes, you could allocate it on the stack. I think back then (still?) a filename could be at most 260 characters, each encoded with 16 bits, so about 52k of stack allocation.
- wongarsu 7d ago52k on the stack is pretty significant, given Windows defaults to just 1MB stack size per thread
- adrianmonk 7d agoYou could use a linked list. Practically speaking, I might just allocate an array of 100 pointers. That's only 400 bytes. Then as you encounter each filename, allocate just enough memory for the actual length of the string (plus null terminator) and store the pointer in the array.
- ulrikrasmussen 6d agoThat will require a second pass though, because you have to free all your strings again.
- wky 7d agoA mentally simpler, though slightly biased algorithm is for each item, randomly generate a uint64 (arbitrary bit size) and switch to the new item if and only if the number generated is greater than or equal to all previously seen numbers. The end result is equivalent to randomly generating a number for each item and picking the item with the largest associated number.
- aimor 6d agoYou could even calculate the 100 random numbers up front and potentially stop iterating early.
- rietta 7d agoI love the understated "some time ago" linking to a 2004 blog post. Raymond has been at this a long time :-)
- SoftTalker 7d agoI love that 2004 sounds like "some time ago" to some people. Seems like yesterday to me.
- rietta 7d agoIsn't that the truth! I remember it very, very well. Vividly even.
- iJohnDoe 7d agoInteresting topic. I configured an account for someone with an Asian last name and it chose the fortune cookie. Probably not voodoo, but it never seemed 100% random. More like some correlation was being done.
- nerdo 7d agoThere's a better way to do this, you use inverse CDF to avoid all the RNG calls. Generate a random number, then skip items until you reach that number: selectRandomFromIteratorOptimized(iterator) { if (!iterator.moveNext()) { return null; } var winner = iterator.current(); var count = 1; while (true) { var u = random_float_open(0.0, 1.0); var skip = (int)Math.Floor(Math.Log(u) / Math.Log(1.0 - (1.0 / (count + 1)))); for (var i = 0; i < skip; ++i) { if (!iterator.moveNext()) { return winner; } ++count; } if (!iterator.moveNext()) { return winner; } ++count; winner = iterator.current(); } }
- canucker2016 7d agoBack in the day, Windows OS kernel programming avoided use of floating point numbers - certainly transcendental functions would've been frowned upon - when CPUs didn't include an FPU. I don't know if they've relaxed this since the days of non-FPU CPUs - anyone know? If they let the Weather app use a webview, there must be some floating point usage in there. This code is at a much higher level though - at the user shell level, explorer.exe. Anyways, asking Google's AI to remove the above code's use of floating point results in code resembling the original version.
- amag 6d agoBetter in which way? It doesn't seem like the RNG is much of a bottleneck[0]. So this code is just more complicated than the original[1] IMO. It is also most likely more costly by involving a bunch of extra divs, logs and (for XP-level HW) floating points, though admittedly the bottleneck on XP-level HW was most likely still the disk. Trying to best Windows devs on performance becomes almost comical if you read the comment for the RtlRandomEx: it is faster than RtlRandom() since it saves one multiplication, one addition and one modulus operation. This almost doubles the performance since it halves the number of clocks even on a pipelined Integer Unit such as the P6/ia64 processors i.e. ~ 52% perf gain. [0]: https://github.com/tongzx/nt5src/blob/daad8a087a4e75422ec96b7911f1df4669989611/Source/XPSP1/NT/base/ntos/rtl/random.c#L120 https://github.com/tongzx/nt5src/blob/daad8a087a4e75422ec96b... [1]: https://github.com/tongzx/nt5src/blob/daad8a087a4e75422ec96b7911f1df4669989611/Source/XPSP1/NT/shell/shell32/userpict.cpp#L458 https://github.com/tongzx/nt5src/blob/daad8a087a4e75422ec96b...
- adrianmonk 7d ago> it’s more efficient because it reduces the amount of calls into the file system OK, but isn't the kernel keeping the directory listing in the disk cache? Won't that prevent extra physical I/O if you do just read the directory twice? If so, then in the second pass, it's all cache hits, and you're just paying the cost of calling into the file system. Hopefully that's pretty fast. But even if not, it's still absolutely dwarfed by the physical I/O required for the first pass. Windows XP era storage was spinning hard drives, not flash. And if not, then I'm probably going to put my user icon coding task on the back burner and go ask the kernel team why a seemingly very common usage pattern isn't optimized. (I realize he's not claiming the performance benefit was significant. I'm just trying to see it in the right perspective.)
- VVIQ2 6d agoThat's clever. I wonder if this was done by an intern during his summer internship :)
- majorchord 6d agoWouldn't it be even more random (and randomly faster) to break out of the while loop when a winner is found? That way you are not always iterating over the entire list. Perhaps a math/statistics expert can tell me why that is a bad idea.
- tyrust 6d agoIf you break early, then you haven't given items later in the list the chance to be selected. You need to go through the entire list in order for every item to have an equal probability of selection. I didn't get it at first, either, and the Wikipedia article didn't do it for me. This explanation finally got me there: https://florian.github.io/reservoir-sampling/ https://florian.github.io/reservoir-sampling/
- majorchord 6d agoBut wouldn't changing the probability be even more random?
- bspammer 6d agoIf you read the "Adapting Probabilities" section of the link above, there's a nice explanation of why changing the probability works.
- Crestwave 6d agoThe first iteration has a 100% chance of being marked as a winner. It only balances out to the same odds as a random selection because of the chances of it getting overwritten by the succeeding files.
- cpeterso 6d agoRaymond’s selectRandomFromIterator algorithm requires iterating over all the files. It seems like querying the file system for the number of files in a directory should be an O(1) operation. Then you just select random number N between [1, number of files] and iterate to the Nth file. Why does Raymond assume counting the files is an O(n) operation?
- orf 6d agoBecause counting the files is not an O(1) operation? It would be cool if it was, but that’s not reality?
- cpeterso 4d agoYou’re right. I looked it up: getting the number of files in a directory in FAT and FAT32 file systems is O(n). I had assumed the count would be recorded in an inode-like structure but instead the file system must scan a directory table to count the non-null entries.
- thenthenthen 6d agoSome example images would have been nice!
- anonymousiam 6d agoArticle reminded me of this: https://www.snopes.com/fact-check/microsoft-outlook-bill-gates-mugshot/ https://www.snopes.com/fact-check/microsoft-outlook-bill-gat...
- eru 6d agoThe solution posted still requires O(n) calls to your random number generator. You can do it in something like O(log n) calls while still sticking to a single forward only pass. (But compared to reading the filesystem the rng calls were probably treated as free.)