What algorithm did Windows XP use to choose your initial user picture?
Posted by soheilpro 2 days ago
Comments
Comment by mawadev 2 days ago
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.
Comment by cabirum 2 days ago
Its not like windows is the pinnacle of software craftsmanship.
Comment by kevin_thibedeau 2 days ago
Comment by Aurornis 2 days ago
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.
Comment by CamperBob2 2 days ago
Comment by dwattttt 2 days ago
Comment by mawadev 2 days ago
Comment by CamperBob2 2 days ago
Comment by dwattttt 2 days ago
Comment by lyorig 2 days ago
Comment by cloudfudge 2 days ago
Comment by Hydraulix989 2 days ago
Being tenured and one of the top engineers in your company with a very proven track record gives you quite a bit more freedom.
Comment by xp84 2 days ago
Comment by alex_suzuki 2 days ago
Comment by dyllon 2 days ago
Comment by bigstrat2003 2 days ago
Comment by jasomill 1 day ago
Comment by 98codes 2 days ago
Comment by darig 2 days ago
Comment by petya415 2 days ago
Comment by jasomill 1 day ago
Which sort of makes sense. I'm not sure technical trade secrets have ever played much of a role in Microsoft's success.
With or without source code, programmers have been digging at the internals of Microsoft OSes for fun and profit since the DOS days, and Microsoft has always seemed to recognize that developers and customers relying on the undocumented nuances of their products benefits them far more than understanding them benefits their competitors.
Comment by fred_is_fred 2 days ago
Comment by EMIRELADERO 2 days ago
Comment by ycuser2 2 days ago
Comment by lr0 2 days ago
Comment by Philpax 2 days ago
Comment by sph 2 days ago
If it were the Windows 11 source, it'd get nuked immediately
Comment by VCFundedGenYer 2 days ago
Most modern Windows code was written in 1995. Don't assume for one moment that it isn't in production Win11 today.
Comment by kevin_thibedeau 2 days ago
Comment by Sophira 2 days ago
Comment by downrightmike 2 days ago
Comment by Sopel 2 days ago
Comment by bonzini 2 days ago
Interestingly, when reading Raymond Chen's article I thought "reservoir sampling would compare the random number (between 1 and n) to 1, not to n, because that extends more easily to picking more than one element" - and that's what the actual Windows code uses.
Comment by Sopel 2 days ago
> it’s more efficient because it reduces the amount of calls into the file system, which is where the bottleneck is
Upon reading it a few times I think the article is alluding to a crappy two-pass solution where you don't store a filename but instead an index into a directory, which is flawed anyway due to being racy.
Comment by impoppy 2 days ago
Comment by carrja99 2 days ago
Comment by VCFundedGenYer 2 days ago
Comment by scrumper 2 days ago
Comment by rhplus 2 days ago
Comment by layer8 2 days ago
Comment by madibo3156 2 days ago
Comment by layer8 2 days ago
Comment by linepogl 2 days ago
Comment by sltkr 2 days ago
Comment by layer8 2 days ago
Comment by pixl97 2 days ago
Comment by ajsnigrutin 2 days ago
Comment by cgio 2 days ago
Comment by jasonvorhe 2 days ago
Comment by moritzwarhier 2 days ago
https://jakeludington.com/2003/12/17/create_your_own_windows...
Comment by seba_dos1 2 days ago
Comment by Maken 2 days ago
Comment by mrweasel 2 days ago
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.
Comment by pndy 2 days ago
I had tons of "Visual Styles" back then and in the last XP days I opted for grayish Royal or Royale. It's such shame that MS has abandoned Watercolor theme - that was a middle ground: interface was updated and yet, still similar to classic design. And it was even in some elements flat before that style become a dominant. Luckily we're slowly moving away from that and I won't be missing it.
Comment by agumonkey 2 days ago
i kinda miss xp at a cultural level since it was a bit the end of that computing culture cycle (after that apple started to dominate and ubuiquitous computing influenced desktop ui)
Comment by Intermernet 2 days ago
When did Apple dominate? I'm not trying to hate on Apple here, but there's this weird belief that Apple have had a lead in personal computer OS market share at some point in the last few decades, and it isn't really true since about 1984.
You can argue that they should dominate, but that doesn't seem to have happened.
Comment by agumonkey 2 days ago
Comment by 2muchcoffeeman 2 days ago
Comment by unregistereddev 2 days ago
Comment by Maken 2 days ago
Comment by afzalive 2 days ago
I eventually got used to it and ended up liking it.
Comment by deltoidmaximus 2 days ago
For awhile I ran XP 64-bit though, that did do one thing 2000 couldn't do.
Comment by stingraycharles 2 days ago
Comment by alex_suzuki 2 days ago
Comment by gschizas 2 days ago
Comment by TazeTSchnitzel 2 days ago
Comment by mrweasel 2 days ago
Comment by bsoqk 2 days ago
>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)
Comment by YPPH 2 days ago
It's all been downhill from there as far as UX goes.
Comment by delta_p_delta_x 2 days ago
Comment by kasabali 2 days ago
Comment by amiga-workbench 2 days ago
Comment by fractal618 2 days ago
Comment by rzzzt 2 days ago
Comment by meerita 2 days ago
Comment by edoceo 2 days ago
Comment by TheAmazingRace 2 days ago
Comment by edoceo 2 days ago
Comment by sunaookami 2 days ago
Comment by medwards666 2 days ago
Comment by Maken 2 days ago
Comment by sunaookami 2 days ago
Comment by ksncksndsh 2 days ago
Its Vista. Like it or hate it. It’s Vista
Comment by CalRobert 2 days ago
Comment by PalmPilotProMax 2 days ago
Comment by lirolero 2 days ago
nobody cares
Comment by ape4 2 days ago
Comment by ygra 2 days ago
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).
Comment by chungy 2 days ago
This is more-or-less unique to ZFS. Other file systems even on Linux and FreeBSD generally don't provide this behavior.
Comment by wongarsu 2 days ago
Comment by tredre3 2 days ago
Most unix filesystems use inodes. inodes have the same format whether they represent a file or directory. So directory have a (usually unused) size member. NTFS doesn't use inodes, but the records in the MFT work the same way.
When adding or removing a file from a directory, you have to update the modification time of the folder, so you have to rewrite the entire inode anyway. Updating the size/file count at the same time would be free.
In my opinion the likely reason why file count isn't tracked is a lot more pedestrian: It wasn't tracked initially and we can never add it to existing file systems because the metadata would get out of sync if the FS was mounted on a kernel with no count support.
I base this assumption on the fact that many modern file systems do indeed keep track of the count.
Comment by eventualcomp 2 days ago
Comment by conorcleary 2 days ago
Comment by adrianmonk 2 days ago
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.)
Comment by rietta 2 days ago
Comment by SoftTalker 2 days ago
Comment by rietta 2 days ago
Comment by Aditya_0315 2 days ago
Comment by ang_cire 2 days ago
Comment by wky 2 days ago
Comment by aimor 1 day ago
Comment by nerdo 2 days ago
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();
}
}Comment by canucker2016 2 days ago
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.
Comment by amag 2 days ago
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/daad8a087a4e75422ec96b...
[1]: https://github.com/tongzx/nt5src/blob/daad8a087a4e75422ec96b...Comment by bhaney 2 days ago
Comment by daveoc64 2 days ago
Comment by ulrikrasmussen 2 days ago
Comment by wongarsu 2 days ago
Comment by adrianmonk 2 days ago
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.
Comment by ulrikrasmussen 1 day ago
Comment by ulrikrasmussen 2 days ago
Comment by wongarsu 2 days ago
Comment by wat10000 2 days ago
Comment by cpeterso 1 day ago
Why does Raymond assume counting the files is an O(n) operation?
Comment by orf 1 day ago
Comment by anonymousiam 1 day ago
Comment by eru 1 day ago
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.)
Comment by dsego 2 days ago
Comment by yoz-y 2 days ago
You still need to see all of the items once.
Imagine you have 2 items.
First one has 100% chance to be selected. So it does. Then the second has 50% chance to be selected. If it isn’t you effectively chosen the first one and have 50/50 chance to return either.
Now you add a third item. There is 50/50 chance of having either selected. And 1/3 chance of replacing the selection with the new one. Resulting in a 1/3 chance of selecting any of the three. (Because 1/2-1/6 = 1/3) 1/6 because there is 50% chance you will “steal” the selection.
Comment by Elte 2 days ago
Comment by Anon_troll 2 days ago
If you are at picture 1, you have 100% chance of selecting it as the current winner.
If you are at picture 2, you have 1/2 chance of selecting it as the current winner, or 1/2 chance of keeping the previous fairly selected winner.
At picture 3, 1/3 chance of picking it, or 2/3 chance of retaining the previous fairly-selected winner. There are two of them, so 1/3 chance of each.
At picture n, you have a 1/n chance of picking it, or an (n-1)/n chance of retaining the previous fairly-selected winner. There are n-1 previous pictures, so all of them have had 1/n chance of being picked.
At every single step, there is the invariant of all pictures being considered that far having had an equal chance of being selected, and the next step always retains the invariant.
Comment by matsemann 2 days ago
Comment by dsego 2 days ago
Comment by quentinkent1 2 days ago
Comment by arpadav 2 days ago
Comment by fschuett 2 days ago
pics[Math.random() * len(pics)]
... assuming that random() gives you a number from 0..1 - but that's why it feels "wrong".Comment by Anon_troll 2 days ago
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.
Comment by akdev1l 2 days ago
Comment by kleiba2 2 days ago
Comment by dsego 2 days ago
Comment by majorchord 2 days ago
Perhaps a math/statistics expert can tell me why that is a bad idea.
Comment by tyrust 2 days ago
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/
Comment by majorchord 2 days ago
Comment by bspammer 1 day ago
Comment by Crestwave 1 day ago
Comment by bayindirh 2 days ago
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.
Comment by wongarsu 2 days ago
Different teams with different goals and different management
Comment by Sohcahtoa82 2 days ago
Not to mention the stack ranking policies that caused engineers to sabotage other people's work and avoid collaboration in order to keep themselves high on the stack in order to avoid being fired.
Comment by airstrike 2 days ago
I get what you mean, but it's really hard for any organization this size to drive consistent quality across the board.
Comment by waz0wski 2 days ago
Yep..
And image files were, and continue to be, a huge exploit attack vector
Comment by bayindirh 2 days ago
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.
Comment by amelius 2 days ago
Just like the rest of us.
Comment by amelius 2 days ago
Comment by bayindirh 2 days ago
Even if you work on exciting things, the project will always have boring parts.
You'll need to develop these parts as well, so be prepared and show the same respect to all parts.
So, I'd personally rather work on all parts equally well rather than winging boring parts and create something subpar.Comment by amelius 2 days ago
Comment by iJohnDoe 2 days ago
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.
Comment by bombcar 2 days ago
Comment by reddalo 2 days ago
Comment by moritzwarhier 2 days ago
I think it's true, but not sure if I'm just falling victim to false memories... help?
Comment by TazeTSchnitzel 2 days ago
Comment by bhaney 2 days ago
Comment by abhinavk 2 days ago
Comment by NitpickLawyer 2 days ago
Comment by bombcar 2 days ago
Comment by xx_ns 2 days ago
Comment by VVIQ2 2 days ago
Comment by thenthenthen 1 day ago
Comment by frou_dh 2 days ago
Comment by vishnuaniyan 2 days ago
Comment by KellyCriterion 2 days ago
A simple rand/mod based on first character of username should be sufficient?
Comment by lentil_soup 2 days ago
Comment by moffkalast 2 days ago
Comment by elgertam 2 days ago
Comment by throwaway219450 2 days ago
But then it occurred to me that XP was of an era when you would absolutely spend an afternoon downloading some megapack of 10000 cool user icons.
Comment by herywort 2 days ago
Comment by bombcar 2 days ago
Comment by consp 2 days ago
Comment by nkrisc 2 days ago
Comment by KellyCriterion 2 days ago
Comment by sltkr 2 days ago
Comment by KellyCriterion 1 day ago
Comment by stephenlf 2 days ago
Comment by KellyCriterion 2 days ago