# A Little OffCode, Computers, Photography and Guns

12Dec/101

## Choosing an SSD (A more different S)

I've been periodically going back and revisiting the results for my SSD analysis script for newegg.com. The last few times I ran it I noticed that it was broken. It looks like newegg has modified a few things in their power search results page. One thing which is a little obnoxious[1] is that they no longer include the capacity in the description of the item or as a feature in the feature list when viewing the results page. This only seems to be an issue on the SSD page although I can't figure out why they decided it didn't need to be there in the first place. I see it this way: SSD's are first and foremost a storage device, you'd think that one of the most important features that should be listed with every SSD is the capacity at least.

Anyway, this change broke my script which I had been meaning to rewrite since regular expressions are definitely not the most efficient or cleanest way to parse HTML. I've been working with XML a more often lately despite my original prejudice against it for being a really bloated way to transfer data. One thing I discovered that makes XML a lot less painful is XPath[2] which is an incredibly useful "language" for selecting data from an XML document.

Once I had gone through and read several tutorials and references about XPath I set out to use it in writing a show calendar script which parses data from tvrage.com's XML API. After that useful exercise I realized I could very easily and cleanly apply it to my SSD analysis script. Since HTML is similar in nature to XML[3] I set out to parse Newegg's results page using XPath. This presented the first problem: Newegg's page isn't strictly XML or even XHTML for that matter. After a great deal of googling and research I landed on the lxml[4] website which as it turns out has an HTML parser for navigating and extracting data from HTML in the same way you would from an xml.etree.ElementTree[5]. With this in mind I immediately began rewriting the script.

First off lets consider my criteria for a "good" SSD on Newegg. The SSD can be either the typical 2.5" form factor, or a PCI-Express card[6]. The interface can be SATAII, SATAIII or PCI-Express. Capacity must be greater than or equal to 120GB[7]. Last but not least, the disk should be sub $300[8]. The above requirements give us the following power search[9] which we will be using as the source for the script:  123456 url = "http://www.newegg.com/Product/ProductList.aspx?Submit=Property&N=100008" + \ "120&IsNodeId=1&maxPrice=300&OEMMark=1,0&PropertyCodeValue=4213:30854,421" + \ "3:41472,4213:47725,4214:46019,4214:72313,4214:57574,4214:58118,4214:3941" + \ "6,4214:47732,4214:30849,4214:47171,4214:46300,4214:77918,4214:72311,4214" + \ ":77919,4214:55178,4214:47733,4214:57755,4214:44038,4215:55552,4215:47726" + \ ",4215:41071&bop=And&Pagesize=100" Now the first thing that made me cringe as I was rewriting this was the fact that I would basically have no choice but to load each individual product page from the results page as capacity is no longer included in either the description or the features list of each product in the results page. Eventually I will get around to multi-threading this to make it a little less painful, or I'll get lucky and Newegg will add the capacity feature back to the item listing in power searches for SSD's. The following is the full source code of the parser:  12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 import re, math from lxml import etree url = "http://www.newegg.com/Product/ProductList.aspx?Submit=Property&N=100008" + \ "120&IsNodeId=1&maxPrice=300&OEMMark=1,0&PropertyCodeValue=4213:30854,421" + \ "3:41472,4213:47725,4214:46019,4214:72313,4214:57574,4214:58118,4214:3941" + \ "6,4214:47732,4214:30849,4214:47171,4214:46300,4214:77918,4214:72311,4214" + \ ":77919,4214:55178,4214:47733,4214:57755,4214:44038,4215:55552,4215:47726" + \ ",4215:41071&bop=And&Pagesize=100" featureMap = { 'Capacity': 'capacity', 'Sequential Access - Write:': 'write', 'Sequential Access - Write': 'write', 'Sequential Access - Read:': 'read', 'Sequential Access - Read': 'read', 'Interface Type': 'interface', 'Brand': 'brand', 'Model': 'model', 'Series': 'series' } speed_re = re.compile(r'(\d+)\s?MB/s') capacity_re = re.compile(r'(\d+)GB') parser = etree.HTMLParser() # tree = etree.parse("temp.html", parser) tree = etree.parse(url, etree.HTMLParser()) root = tree.getroot() items = [] for node in root.findall(".//div[@class='itemCell']"): item = {} # Get link link = node.find(".//a[@title='View Details']") item["link"] = link.attrib["href"] # Get feature list (loads each item's url, should multi-thread this in the future) itemPage = etree.parse(item["link"], etree.HTMLParser()).getroot() featureList = map(lambda n: n.text, itemPage.findall(".//fieldset/dl/dt")) valueList = map(lambda n: n.text, itemPage.findall(".//fieldset/dl/dd")) features = zip(featureList, valueList) for feature, value in features: if value is not None and feature in featureMap: # If it's a speed feature parse out the speed if featureMap[feature] in ("read", "write"): item[featureMap[feature]] = min(map(lambda x: int(x), speed_re.findall(value))) # If it's a capacity feature, parse out the capacity elif featureMap[feature] == "capacity": item[featureMap[feature]] = min(map(lambda x: int(x), capacity_re.findall(value))) # If the value doesn't need to be parsed, just store the value in item else: item[featureMap[feature]] = value.strip() # Get price price = map(lambda n: n.text, node.findall(".//li[@class='priceFinal']/*")) item["price"] = float(''.join(price[1:])) # Only add the item if it has the features we need in it if "read" in item and "write" in item and "capacity" in item and "series" in item: score = (item["read"] * item["write"] * item["capacity"]) / ((math.log(abs(item["read"] - item["write"])) + 1) + item["price"]) item["score"] = score items.append(item) sorted = {} for item in items: # Open addressing like in a hash table, so we don't wind # up with any collisions, unlikely but good practice anyway score = item["score"] while score in sorted: score += 1 sorted[score] = item sortOrder = sorted.keys() sortOrder.sort() sortOrder.reverse() headers = ['brand', 'series', 'model', 'link', 'interface', 'price', 'capacity', 'read', 'write', 'score'] print '\t'.join(headers) for key in sortOrder: item = sorted[key] print '\t'.join(map(lambda x: str(item[x]), headers)) At this point if you've gone through and read the entire script you'll probably notice that I've made a slight change to the scoring equation, it has been changed from the following: $\frac{\text{Read} \times \text{Write} \times \text{Capacity}}{\text{Price}}$ To the following: $\frac{\text{Read} \times \text{Write} \times \text{Capacity}}{(\log_{10}(|\text{Read} - \text{Write}|) + 1) \times \text{Price}}$ I discovered that using the difference in read//write speed heavily penalized drives with anything greater than 10MB/s difference. So I figured that it may be a little more subtle to simply penalize drives based on the magnitude of the difference. Now you're probably wondering: "When is this blathering idiot going to get to the damned results already?". And you'd be pleasantly surprised to know that I'm getting to them as you waste your time reading this.  Manufacturer: OCZ OCZ G.Skill OCZ Series: RevoDrive Vertex 2 Phoenix Pro Series Agility 2 Capacity: 120GB 180GB 120GB 120GB Read: 540MB/s 285MB/s 285MB/s 285MB/s Write: 490MB/s 275MB/s 275MB/s 275MB/s Item: N82E16820227578[10] N82E16820227602[11] N82E16820231378[12] N82E16820227593[13] Price:$299.99 $294.99$214.99 $214.99 As you can see the RevoDrive far out-scores all the rest of the SSD's considered in this analysis. The main reason is that they've essentially included two 60GB SSD's on the same card and you're expected to perform software raid on them in your own system[14]. Despite the incredible speeds they boast I don't think I would purchase one of these to use as my OS//Program disk because compatibility is a major limitation. You must be sure that your motherboard's BIOS supports booting via PCI-Express cards. And last but not least, the main reason I would pass up this card is the lack of TRIM support. As far as I can tell these cards do not support TRIM which is a major downside as far as I'm concerned. The second disk in the list is the OCZ Vertex 2 180GB version. I'd probably skip this one just because I don't really consider the extra 60GB worth the extra$80.

Which leaves me with the last two disks which are as far as my analysis is concerned, identical. If you take into account the detailed features you'll notice that the G.Skill claims 50k IOPS on the 4k Random write test which seems a bit... optimistic. The OCZ makes no such claim and as far as I'm concerned both disks are more less the same thing. So it's pretty much up to brand preference at this point.

1. I've already sent feedback to them suggesting that they fix this. []
2. Only if the XML parser you're using supports it, which it seems is not a whole lot of them. At least not all of them support the full specification which is annoying since nobody really seems to document which bits and pieces they support and which whey don't. []
3. Although not necessarily XML depending on the particular doctype you've chosen, Newegg's is transitional HTML. []
4. lxml: http://codespeak.net/lxml/ []
5. xml.etree.ElementTree: http://docs.python.org/library/xml.etree.elementtree.html []
6. Some of the PCI-Express SSD's are stupidly fast and more expensive except that it doesn't look like any of them support TRIM yet which is a major problem for me. []
7. It is rare that I have a matured (read: haven't reformatted in a while) install of windows along with all of my most commonly used programs and games that exceeds 60GB so I estimate that doubling this should accommodate for any sudden urges to install really big things. []
8. I can't really justify spending much more than $300 on a single storage device. It had better be one hell of a storage device if I ever find myself spending more than$300 on it. []
9. This will likely need to be updated at least once a month as Newegg is constantly adding new criteria and changing things. []
10. OCZ RevoDrive []
11. OCZ Vertex 2 []
12. G.SKILL Phoenix Pro Series []
13. OCZ Agility 2 []
14. They show up as two separate physical devices despite being located on the same card. []
9Oct/100

## Choosing an SSD (Update)

My brother is in the planning stages of building a new desktop. One of the things he's planning on doing differently from his last build[1] is using an SSD for OS + Programs.

I had mentioned to him previously that I a wrote a program for helping to choose an SSD based on what SSD's are meant for and are good at doing. So he asked if I could recommend him one. Below are the results of the latest run of my script based on the most current listings[2] of SSD's newegg offers.

 Manufacturer: OCZ G.Skill OCZ Series: Agility 2 Phoenix Pro Vertex 2 Capacity: 120GB 120GB 120GB Read: 285MB/s 285MB/s 285MB/s Write: 275MB/s 275MB/s 275MB/s Item: N82E16820227543[3] N82E16820231378[4] N82E16820227551[5] Price: $235.99$239.99 $240.00 It looks like OCZ has two of the top three places this run and G.Skill is still maintaining one of the top three from before. Between the 3 of them I think i would likely still go for the G.Skill just because of personal preference despite there not really being any significant differences between the three. Excepting price of course. 1. Which incidentally was right when SSD's were just becoming available to the average consumer. [] 2. As of this date 10/09/2010. [] 3. OCZ Agility 2 [] 4. G.Skill Phoenix Pro [] 5. OCZ Vertex 2 [] 11Aug/100 ## Choosing an SSD Before I started my new job I had an inordinate amount of free time and for a majority of that time, nothing to spend it doing[1]. I was still thinking about my desktop wishlist[2] and about choosing a better SSD than the one I had previously selected[3]. A long time ago when I was following the HDD market since I was looking to buy some bulk storage I wrote a php script which loaded newegg's product list based on some search parameters you provided newegg's productlist.xml[4]. The script would then parse the list and produce a list sorted based on price per gigabyte. Which is useful when you're in the market for capacity[5]. I decided to do more or less the same thing with SSD's except this time I did it in python since I'm rusty on PHP and I didn't want to mess with setting up a web server to test on. So I got started by doing a power search on newegg for the specific flavor of SSD I was looking for. The search parameters are as follows: • 2.5" Form Factor • SATA II/III • 120GB or Greater • Less than$300
• Retail or OEM
• Support TRIM Command

As of this writing those particular search parameters narrows the result to 17 SSD's. Now comes the code. Before I started coding I needed some way to sort them according to what I thought was important. The metric is as follows:

$$\frac{\text{Read} \times \text{Write} \times \text{Capacity}}{|\text{Read} - \text{Write}| \times \text{Price}}$$

After looking closer at the scores this produces I noticed that it heavily penalizes drives with huge differences between read and write speeds which effectively weeds out drives that still have acceptable read//write speeds. So I removed that section of the metric producing:

$\frac{\text{Read} \times \text{Write} \times \text{Capacity}}{\text{Price}}$

The basic idea behind this scoring measure is that sequential read and write speeds are important, as well as capacity. Price and difference between sequential read//write are considered bad[6]. In the equation read and write refer to sequential read and write speeds. The ratio of these will produce a score of the SSD's overall performance for capacity, read//write speeds and price.

The code is relatively simple in purpose. Load the data and parse it into a dictionary then sort based on the metric above.

 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 import urllib2, re # url = " # http://www.newegg.com/Product/ProductList.aspx?Submit=Property&Subcatego # ry=636&Description=&Type=&N=100008120&IsNodeId=1&srchInDesc=&MinPrice=&M # axPrice=&OEMMark=1&OEMMark=0&PropertyCodeValue=4213:30854&PropertyCodeVa # lue=4214:30848&PropertyCodeValue=4214:39416&PropertyCodeValue=4214:30849 # &PropertyCodeValue=4214:39415&PropertyCodeValue=4215:55552&PropertyCodeV # alue=4215:41071&PropertyCodeValue=4215:46319" # data = open("temp.html", "w") # data.write(urllib2.urlopen(url).read()) # data.close() raw = open("temp.html").read() item_re = re.compile(r'
(.*?)
') feature_re = re.compile(r"
•  (.*?)
• ") feature_list_re = re.compile(r'(.*?)\s?\#?\s?:\s?\s?(.*?)') speed_re = re.compile(r"(up to )?(\d+).*?MB/s") capacity_re = re.compile(r"(\d+)GB") price_re = re.compile(r"\$(\d+).(\d+)") item_list = [] valid = ['Read', 'Item', 'Interface', 'Capacity', 'Model', 'Write', 'Size'] for item in item_re.findall(raw): current = {} no_label = [] features = feature_re.findall(item) current["Size"] = features[0] current["Capacity"] = features[1] current["Interface"] = features[2] for feature in feature_list_re.findall(item): if feature[1].find("\r") != -1: current[feature[0]] = feature[1].split("\r")[0] else: current[feature[0]] = feature[1] current["Read"] = int(speed_re.findall(current["Sequential Access - Read"])[0][1]) current["Write"] = int(speed_re.findall(current["Sequential Access - Write"])[0][1]) current["Capacity"] = int(capacity_re.findall(current["Capacity"])[0]) for feature in current.keys(): if feature not in valid: del current[feature] current["Price"] = float('.'.join(price_re.findall(item)[0])) current["Item"] = "http://www.newegg.com/Product/Product.aspx?Item=%s" % (current["Item"]) item_list.append(current) sorted = {} for item in item_list: ratio = (item["Read"] * item["Write"] * item["Capacity"]) / (item["Price"]) sorted[ratio] = item sort_order = sorted.keys() sort_order.sort() sort_order.reverse() for key in sort_order: #print '\t'.join(map(lambda x: str(x), sorted[key].keys())) print '\t'.join(map(lambda x: str(x), sorted[key].values())) Now given that there is quite a lot of data to present and analyze all at once I've decided it would be easiest to just provide you with a pretty graph[7]: If you look closely at the scores of all the disks in the query, you'll notice that this is a noticeable gap between the top 3 and the rest. They are as follows:  Manufacturer: A-DATA Patriot G.Skill Series: S599 Inferno Phoenix Series Capacity: 128GB 120GB 120GB Read: 280MB/s 285MB/s 285MB/s Write: 270MB/s 275MB/s 275MB/s Item: N82E16820211471[8] N82E16820220510[9] N82E16820231372[10] Price:$295.99 $289.99$299.00

I noticed that if you ignore capacity in the metric then the Patriot Inferno is the clear winner here. So as it turns out the Western Digital SiliconEdge I had selected when I first wrote the wishlist wasn't the best drive for my needs. But then I've always had a soft-spot for Western Digital. But now I'm convinced that the Patriot Inferno is the SSD I'll be getting unless by the time I get around to buying one there are better options[11].

1. Nothing worth-while anyway []
2. See previous post: Wishlist. []
3. Western Digital SiliconEdge 128GB SSD []
4. Which no longer exists in it's original form. []
5. Which I was. []
6. Although we're excluding read//write speed difference. []
7. Scores have been normalized to 100%. []
8. A-Data S599 []
9. Patriot Inferno []
10. G.Skill Phoenix Series []
11. Which there probably will be. []
22Jul/100

## Wishlist

I've noticed recently that I tend to spend a lot of time shopping for things I can't afford when I don't have any excess income. I can't really tell if it's just because I'm bored a lot more often over the summer. Especially this one since I've been unemployed for the maojority of it so far[1].

As it stands there is a rather long list of things I intend on buying//upgrading//replacing in the future. First and foremost on this list is a new laptop since my current ASUS Eee-PC 1000H is driving me nuts. It's useful for... writing, and not even that sometimes. For the last year I've used it almost strictly for taking notes in class, which it does well enough. But using it for anything else is essentially impossible. I've found this to be even more true in the last few weeks since I've been spending every other weekend with my parents on their ranch or in Cheyenne. I've just been using it when I went since it's pretty impractical to take my desktop with me everytime. Especially considering a lot of the stuff I work on needs a decent amount of bandwidth and my parents' internet connection is satellite based on their ranch at least so it would be pointless to try and get any real work done.

I've essentially decided that my next laptop will be a 13" Macbook Pro. The main reason is that for the amount of money I intend on spending on a new laptop the Macbook Pro is far superior in both build quality and components to the equivelant Dell which is the manufacturer I've used for all my mobile computing needs until my netbook. Easy decision don't you think?

The next item on my list was building a new desktop. I only really need to replace the core components of my desktop since everything else is more or less in good working order. But that's boring so I've made an entire list of components including core and secondary components to build a new desktop, excluding optical drive and hard drives[2]

The first part I always start with when building a wishlist[3] is the CPU and for this particular one it was a pretty simple choice. Intel's Core i7 series is pretty much the way to go when building a workstation. In this case there were only really two requirements I had for selecting the particular Core i7 I need for this build.

• $0 < Price <$500
• Supports Triple Channel DDR3

These requirements narrow down the selection to two processors. The Core i7-920 and the Core i7-930. There are only two differences. The 930 is 2.8Ghz and the 920 is 2.66Ghz and the 930 is $10 cheaper than the 920, so it's pretty obvious which one is the one to go with. Intel Core i7-930 Bloomfield 2.8Ghz LGA 1366 130W Quad-Core Model #: BX80601930 Item #: N82E16819115225 Price:$289.99

The second component I select after the CPU is the motherboard. Now this is where it gets tricky because the restrictions I use for selecting a motherboard have a lot less to do with technical capabilities than they do with reliability and proper functionality. This is where newegg becomes the right place to shop. Their product review system is by far the best in the online tech shopping world. I tend to score motherboards based on the number of reviews they receive and the score of the review. This is of course after I've removed motherboards incompatible with the other components I intend on using in the system.

• LGA 1366
• Intel X58
• Intel ICH10R
• ATX form factor

The motherboard that comes out on top after these restrictions is an EVGA board.

EVGA E758-TR Intel X58

http://www.newegg.com/Product/Product.aspx?Item=N82E16813188046

Model #: 132-BL-E758-TR
Item #: N82E16813188046
Price: $269.99 IMIR -$40.00: $229.99 Next up is system memory. This almost always follows from motherboard since some motherboards support odd RAM speeds and I tend to stick with standard speeds since they are a lot less prone to compatibility issues and just work. In this case the motherboard calls for DDR3 1333[4]. I usually filter out for the specific kind of RAM I want which leaves me with a few dozen sets. Then I score based on CAS latency and price. I've used G.SKILL before and was pleased with it and in this case a G.SKILL set won on both price and CAS latency. G.SKILL 3GB (3 x 1GB) DDR3 1333 (PC10666) Triple Channel Model #: F3-10666CL7T-3GBPK Item #: N82E16820231229 Price:$84.99

Now you're probably thinking "Why does he only want 3GB that's puny!". There are some very good reasons for it. First of all I'm not really all that into 64-bit yet, I still have a few devices without 64-bit compatible drivers[5]. For the most part 2GB of RAM has suited me just fine for nearly anything I've ever needed//wanted to do on my desktop until this point, why should I pile in twice or even three times that amount? Besides if I so desire I could just purchase a second set in the future. The only reason I might consider doing that is if I suddenly became obsessed with running a dozen virtual machines simultaneously[6].

Next in line isn't exactly a component I need to buy, but I've been wanting to upgrade for a long time now and I figure a wishlist is the best place to do it. Ever since I saw an article on Gizmodo[7] about the new NVIDIA GeForce GTX 460 I've pretty much been set on that specific chipset. It was pretty easy to select a brand since they're all exactly the same price at this point and I only want the 768MB model. I've been wanting to do some CUDA development so here's my chance.

EVGA NVIDIA GeForce GTX 460 (Fermi) 768MB
Model #: 768-P3-1360-TR
Item #: N82E16814130562
Price: $199.99 Another component I consider to be core but isn't necessarily a core component is the storage device used for the OS. In the past I've strictly used HDD's for my desktop. But since I installed a Patriot 32GB SSD in my laptop I've fallen in love with SSD's for the OS//Programs drive. You might hear people moan and complain about SSD's being disproportionatly priced based on their capacity. Well I've got news for you, you don't buy SSD's for capacity, you buy them for speed. Anyone reasonably knowledgeable about computer components and their functionality would know that. I'm not interested in price per GB as quite a lot of people might be, at least not for SSD's[8]. I'm a lot more interested in price per MB/s sequential read-write. The particular disk that won in this case is one of the new Western Digital SSD's. Western Digital SiliconEdge Blue 128GB SSD MLC 220/170 SR/SW Model #: SSC-D0128SC-2100 Item #: N82E16820250002 Price:$199.99

In case the title of that product doesn't make sense the drive is 220MB/s Sequential Read and 170MB/s Sequential Write.

Everything from this point on I consider to be secondary components as they don't directly do any computation or data transfer//storage.

For this build I've decided that even though I don't need to get a new case, I've added one to the list anyway since my current case is due for an upgrade, especially in regards to aesthetics. I've been oggling this particular case for quite a while now, since it replaced it's predecessor at least. This case won by a long shot in aesthetics and functionality.

Antec P183 Black Aluminum/Steel ATX-Mid
Model #: P183
Item #: N82E16811129061
Price: $179.99 IMIR -$25.00: $154.99 The next item due for an upgrade was actually necessary considering the major increase in power needs for the core components. I've always hated shopping for power supplies because there are far more factors to consider when it comes to selecting one that matches your needs and is of reasonable build quality. If you don't have a decent power supply you may as well just give up. In this case I stuck as close as possible to the power supply I have now. I was only really interested in making sure that there were enough PCI-e power connectors since my current PSU has none. I let the reviews do the majority of selecting for me in this case. Corsair 650W (ATX|EPS)12V Model #: CMPSU-650TX Item #: N82E16817139005 Price:$119.99 IMIR -$30.00:$89.99

This power supply matched most closely to the one I had now, it's simple, doesn't have too many "certifications" and marketing nonsense tacked onto the name and the cables are sheathed in black mesh[9].

Now I don't normally bother with purchasing a 3rd party heatsink//cooling system for my CPU but in this case I had heard mention of a self-contained water cooling system with radiator, pump and CPU waterblock from Corsair. So I checked it out and I am impressed. Since it is self-contained it removes a lot of the frustration with resevoirs and replacing the coolant on a regular basis.

Corsair H50 CPU Cooler
Model #: CWCH50-1
Item #: N82E16835181010
Price: $74.99 The last item in the list is more for interior neatness and organization. I've always hated just leaving components without a proper fastening inside the case. In this situation the SSD I select[10] is 2.5" form factor, suitable for notebooks and less suitable for desktops. So I looked around for a set of 2.5" to 3.5" brackets to secure the drive in one of the HDD bays. iStarUSA 2.5" to 3.5" HDD Bracket Model #: DIY-RP-HDD2.5 Item #: N82E16816215157 Price:$5.99

The subtotal for the build excluding shipping and including all instant mail in rebates comes out to \$1330.91. Pretty good wouldn't you say? For a decently beefy workstation that would likely last me another 5-6 years before upgrading again. I'm currently on the 5th year since a major overhaul of my current system an Intel Core 2 Duo based rig.

1. I do have an interview coming up so wish me luck. []
2. Again, excluding SSD from this list of parts I don't intend to buy. []
3. Always on Newegg.com, they're the de facto standard in online computer components. []
4. DDR3 SDRAM PC10666 []
5. And will probably never be compatible for that matter. []
6. Which I won't, so I won't. []
7. I think. []
8. The only component I consider price per GB on is standard HDD's. []
9. Which lends nicely to aesthetics should I ever decide to show someone my desktop's inards. []
10. Like all SSD's. []