16 ms·
How much your computer can do in a second (2015)
- NoahTheDuke 6y agoThis is a lot of fun! Why the use of Python 2?
- saagarjha 6y agoIt's fairly old: https://github.com/kamalmarhubi/one-second/commits/master https://github.com/kamalmarhubi/one-second/commits/master
- NoahTheDuke 6y agoAh thank you
- sillysaurusx 6y agoI’m still salty that Python 3 fragmented the community so much. Both sides of the debate are equally shrill. Hopefully they won’t merge that latest pattern matching proposal. Talk about impossible to backport code...
- deleted 6y ago[deleted]
- herdrick 6y agoHow is the 'write a byte to disk' loop faster than the empty loop? Maybe xrange() is dominating in the empty loop example.
- krick 6y agoIt's number of bytes, not loop iterations.
- formerly_proven 6y agoBecause it's writing one megabyte per iteration.
- Nitramp 6y agoAs others have commented, it's bytes per second. But also, they are not flushing the file to disk, so this might really just writing to memory (in form of the OS's page cache).
- Sebb767 6y agoGreat idea! However, I found the hash part a bit confusing; why not use hashes per seconds or bytes per second for both of them?
- bigdict 6y agoGreat idea, but this is complicated by having to model the Python interpreter.
- Asraelite 6y agoAgreed, it would be better to stick to a low level language for this. It's made even worse by the fact that some operations will be internally delegated to C code while others are pure Python.
- closeparen 6y agoThis is so important. I see so many people farting around in the problems of highly scalable distributed cloud systems with thousands of nodes, not realizing that single-digit QPS per node is insanity, why don't you look there first? Computers are fast.
- colecut 6y agoI think they do this because their priority is decentralization and not speed
- closeparen 6y agoYou can achieve decentralization with a handful of nodes, and you can manage them using simple techniques without inviting the whole large-scale cluster scheduler problem. What I'm talking about is like 3,000 nodes to serve 15,000 QPS. That seems like a lot of QPS, and so it makes intuitive sense to people that they'd need a big distributed system for it, unless they have a sense of how fast computers actually are.
- H8crilA 6y agoAs this post shows - it really depends on what you're doing :). There are services that can handle 100k QPS on a single machine, no problemo. There are services that can handle as little as 10 QPS per machine. Those are rather extreme cases. A classic example of a "cheap" service is something like Stack Overflow [1] or Wikipedia: serving content that is mostly static; you just gotta configure your caches well. A classic example of an "expensive" service: a search engine, where so many queries cannot be cached (too rare), or are even completely unique (never seen before [2]). [1] https://stackexchange.com/performance https://stackexchange.com/performance [2] https://www.seroundtable.com/google-15-percent-queries-25730.html https://www.seroundtable.com/google-15-percent-queries-25730...
- closeparen 6y agoRight - "those are rather extreme cases." So if you're looking at 5 QPS / node, you should be raising your eyebrows, not automatically reaching for an autoscaling group.
- dang 6y agoIf curious see also 2017 https://news.ycombinator.com/item?id=13960183 https://news.ycombinator.com/item?id=13960183 2015 https://news.ycombinator.com/item?id=10445927 https://news.ycombinator.com/item?id=10445927
- saagarjha 6y agoI'm not sure if you've decided to switch up the usual "past discussion" with "if curious see also", but FWIW the latter suggests to me "here is more material that is tangentially relevant that you might find interesting" while the former is very direct in what it's claiming to link to.
- dang 6y agoI'm just looking for concise wording that no one will misunderstand as somehow critical of the repost. The intention is simply link to interesting things that readers might be curious to look at. If the repost were bad we'd mark it [dupe] instead.
- switch007 6y ago“Past discussions“ seems absolutely fine (and much more precise). Maybe others need to consider if they’re overreacting to two very simple words.
- osrec 6y agoVery interesting! I think every dev should have a sense of how long loops like these take, if only to have a good starting point for where to optimise code (only if needed - * insert quote on premature optimisation *).
- alister 6y ago> How many times can we download google.com in a second? Exact answer: 4 I was a little suprised by this one. Sure, network connections are are going to be much slower than local operations, but where's the time going? Is it mostly the network latency? Google has a lean webpage, so I assume it has nothing to do with google specifically.
- Junk_Collector 6y agoIf your average connection has 100 ms (50 ms would be extremely good but doable these days) of round trip latency to Google.com, then you have a hard upper limit of 10 loads per second just to connect to the system. Then you have to move the data, store it in memory, parse it, and run it.
- ummonk 6y agoI'd be shocked if my latency to Google were even as high as 50 ms. Though downloading http will take 3 round trips for http and four round trips for https which will add up if the connection isn't kept alive after each download. Edit: just tested and got these numbers for myself: 7-13ms to ping google.com 50-80ms to curl http://google.com http://google.com 90-130ms to curl https://google.com https://google.com 140-160ms to curl http://google.com http://google.com http://google.com http://google.com http://google.com http://google.com http://google.com http://google.com http://google.com http://google.com 180-220ms to curl https://google.com https://google.com https://google.com https://google.com https://google.com https://google.com https://google.com https://google.com https://google.com https://google.com So should be able to download something like 20-30 copies of google with keep-alive, and ~10 without.
- Junk_Collector 6y agoYou're absolutely right and speeds to Google have gotten much faster over time. For what it's worth, I just ran a quick ping test and got 26ms average latency to google.com so I should have checked before I posted. Thanks for keeping me in check. Still this is dependent on where you are, your ISP, other general factors, and it's still within an order of magnitude which was the point of the "quiz"
- EdTsft 6y agoOn mobile Firefox (at least for me) nothing appears below the intro message. The last line I see is "Made for you by ...".
- markstos 6y agoComputers are also slow and sometimes getting slower, because real world applications are built with increasing layers of abstractions. while the hardware in the bottom layer is getting faster, the top layer is sometimes slower because there are so many layers and so much complexity in the stack. Take this review of terminal emulator benchmarks: https://lwn.net/Articles/751763/ https://lwn.net/Articles/751763/ Uxterm, released in 1994 is the clear winner. A "modern" terminal like Gnome Terminal has more than 10x the latency. Booted an Electron app lately?
- PragmaticPulp 6y agoA few extra seconds of app startup time or an extra frame of latency in your terminal is a small price to pay for the absolutely massive difference in functionality of newer apps. It’s fun to see how fast apps were when everything was extremely simple, but you can’t dismiss the fact that it was orders of magnitude less capable than modern software. The bottom line is that modern apps are fast enough. I’ve never once thought that my terminal latency is too slow or that a few extra seconds of app startup time made a any impact on my day whatsoever. The difference between the fastest and slowest terminals on that list is less than 30ms, or 3/100ths of a second. Literally less than a blink of an eye. It’s a fun study and enjoyed the article, but the reality is that it just doesn’t matter at all. Anyone suggesting that computers felt faster a decade ago is misremembering the past. Try using a 2008-era computer with a mechanical HDD and you’ll quickly realize that apps did not launch faster back in the day.
- antepodius 6y agoModern programs are 100 times slower, but they definitely aren't 100 times more functional. And speed is a part of functionality and UX! I don't want to have to use a high-powered workstation or a gaming laptop to get reasonable responsiveness in my text editor. Many Javascript-powered websites with 'fancy' canvas features are janky and slow as shit on hardware that's only 10 years old, where as websites that use HTML are still snappy and fast. That 'nothing at all' matters when our current culture involves building layers and layers and mountains of stacks on top of software. That 30 ms compounds, because everyone working on each layer thinks 'hey, this is a bit slow, but it doesn't matter because it's only milliseconds.' Given this, it's obvious that modern software will be as slow and inefficient as it possibly can be before normal people notice and complain (usually only because they've used other equivalent software that's smoother and faster- it's easy to get used to jank, like low FPS in a video game.) I think that people undervalue the cost of all these layers of abstraction.
- markstos 6y agoIn the real world, when I type close to 100 wpm on keyhero.com, the highlighting of the current word can't even keep up with a human typist.
- martincmartin 6y agofor (s = i = 0; i < NUMBER; ++i) { s += 1; } I'm surprised gcc can't figure out that this is NUMBER*(NUMBER-1) and eliminate the loop entirely.
- zozbot234 6y agoIt probably can, at high-enough optimization level.
- jrockway 6y agogcc and clang both perform this optimization for me at -O3.
- martincmartin 6y agoThanks. On godbolt, I see clang do it at -O3. But gcc still has a loop, where the body has add but no mul, although I don't fully understand the body. Where do you see it in gcc? https://godbolt.org/z/sP194Y https://godbolt.org/z/sP194Y
- martincmartin 6y agoThey used -O2, which produces the straight forward loop. [0] But with -O3, for NUMBER > 51, is uses some other odd loop. [1] Seems to be O(n) no matter what though. [0]: https://godbolt.org/z/czcaYf https://godbolt.org/z/czcaYf [1]: https://godbolt.org/z/sP194Y https://godbolt.org/z/sP194Y
- saagarjha 6y agoClang knows what’s up: https://godbolt.org/z/7zKffz https://godbolt.org/z/7zKffz. GCC is adding the numbers four at a time by stuffing 0, 1, 2, 3 in an XMM register, taking a packed addition within the register, and then doing a pairwise packed addition of the register with 4, 4, 4, 4 to get the next four numbers.
- bigdict 6y ago
- bserge 6y agoAnyone interested in how much your brain can do in a second? I'm making a mindmap/chart for that in my quest to better understand natural intelligence and how it could be replicated as AI.
- EricBurnett 6y agoThe brain is always a fun comparison. It's this crazy super-scalar architecture that can do thousands of trillions of primitive operations per second (petaflops), yet with pretty terrible latencies: propagation through synapses on the order of single digit milliseconds, individual neurons only fire order of 1 time per second, input processing latencies in the hundreds of milliseconds, and primitive "logical" algorithms like "how many numbers can you count in a second?" netting out to "less than 10". So we end up in this state where what the brain does well computers are still (comparatively) terrible at, and what computers do well the brain is (comparatively) terrible at. We're slowly bridging that divide, with e.g. TPUs focussing on larger volumes of low precision operations happening in parallel, but we've got a long way to go yet.
- ghj 6y agoThe empty loop in python was surprisingly slow (68,000,000 iterations per second). What is it actually doing here? A 3ghz cpu has 3 billion cycles per second. So it's spending an average of 44 cycles to increment an integer and compare??? (also fun fact, python integers are 28 bytes, but it still doesn't really explain the slowness: `import sys; sys.getsizeof(123456)`)
- smallpipe 6y agoPython might have changed since this was written, but on my machine, with any number, it finishes in 0.0s! My understanding was that to access a variable, python does a dictionary lookup to match the name to a memory location, which would explain what happens with an older python.
- wwright 6y agoThat happens for global lookups, but methods should use a stack-like lookup for local variables which should be much faster IIRC (Personally, I really question the extremely-dynamic-by-default design of that generation of languages; is being able to treat globals as a dictionary occasionally worth forcing a key lookup on every single global use?)
- teraflop 6y agoI just tested this on a Linux box I happened to have running, using the "perf" tool. By my measurements, each iteration takes about 104 instructions, of which 23 are conditional branches, and completes in about 31 cycles. (That's after subtracting about 30 million cycles of startup overhead. Tested with Python 2.7.9 on an Intel i3-4160 processor.) Remember, Python is a bytecode-interpreted language. Each iteration of the loop involves multiple bytecode operations: 2 0 SETUP_LOOP 20 (to 23) 3 LOAD_GLOBAL 0 (xrange) 6 LOAD_FAST 0 (NUMBER) 9 CALL_FUNCTION 1 12 GET_ITER >> 13 FOR_ITER 6 (to 22) 16 STORE_FAST 1 (_) 3 19 JUMP_ABSOLUTE 13 >> 22 POP_BLOCK >> 23 LOAD_CONST 0 (None) 26 RETURN_VALUE Executing each of those instructions means fetching it, jumping to the implementation of the appropriate opcode, and then updating the VM's state -- or, in the case of FOR_ITER, calling the native C function that advances the iterator. Frankly, it's impressive that it's as fast as it is.
- asifgdinio 6y ago>If we just run /bin/true, we can do 500 of them in a second, so it looks like running any program has about 1ms of overhead. This is off by at least three orders of magnitude, at least on my machine. $ time for i in $(seq 1000000); do true; done real 0m1.049s user 0m1.037s sys 0m0.019s This article would be better if it were about computers in general, not about Python. I specifically avoid using Python for anything serious because I find its performance impossible to reason about. Then again, perhaps it's a good thing to have examples that require thinking rather than just reciting the machine's specs like most of these lists I've seen.
- mrob 6y agoYour "true" is probably a shell builtin. Try it with /bin/true instead.
- FastedCoyote 6y agoTwo tips, if you're using Bash: 1. Use the external "true" command. 2. Use {a..b} to expand sequences of numbers as "seq" adds extra overhead. $ time for i in {1..500}; do /bin/true; done real 0m0.983s user 0m0.650s sys 0m0.423s
- deleted 6y ago[deleted]
- smallpipe 6y agoI don't think the explanation for fill_array.c and fill_array_out_of_order.c is correct. Unless you're running on a massive server, you're not getting anywhere near 300MB of cache. Modern CPUs have optimizations that bypass L1 and L2 cache allocation for a continuous burst of writes without reads, so the result here is main memory write speed, not cache allocation.
- bananaface 6y agoBoth examples read from the array before writing, no? So they have to read on each iteration. I don't have a super solid grasp on caching but it seems like his method of out-of-order referencing will still be hitting a valid L1 cache most of the time, so this understates the problem. Am I misunderstanding?
- rjtobin 6y agoThe cartoon picture is that the first example will read everything into cache once, whereas the second example will read everything into cache twice. Cache lines are typically 64-bytes, so to write a single character to main memory the following things happen (again, a cartoon picture): First read the 64-bytes area that contains the byte of interest so that it is owned by my cache (this is called a RFO, "read-for-ownership"). Second, update the byte of interest. Thirdly (at some point) write the cache-line back to main memory. In the sequential case, we just read one 64-byte cache line at a time, update those 64 chars, then write the cache line back to main memory. In the second example, we first update all the even-indexed characters, which still forces us to read in every cache line. Then we loop around and do the odd-indexed characters, at which point we have to read the cache lines all over again (assuming the array is big enough that the whole thing can't fit in cache at once).
- bananaface 6y agoAm I misreading the second example's algorithm? Isn't it allocating like this: 1, 2, 4 3, 8 7 6 5, 16 15 14 13 12 11 10 9, ... And so on? --- Also this part: >Cache lines are typically 64-bytes Right, but I thought when you access an index it caches quite a lot more than 64 bytes from the index. Doesn't it throw a larger chunk of the array onto multiple lines? If that's the case then the first example is making very efficient use of the cache. If the modern CPUs are smart enough to cache backwards and I understand the second example, isn't the second too?
- webdva 6y agoHow fast can a single board computer such as the Raspberry Pi compute the solution to a linear programming problem (i.e., a mathematical optimization problem of the form Ax < b) that has, literally, trillions of constraints? Or can it even be done at all what with the large pool of constraints to navigate through? And how is such a prospect and execution compared to the computations done in the middle of the twentieth century which used weaker computers?
- jancsika 6y agoFor the final one, I'd like to see a comparison showing how many elements can be set for a linked list in one second.
- adverbly 6y agoGrep bytes surprised me. Why is it the exact same as write to memory? Is reading from memory much faster than writing or something? Even then I'm not sure how it wasn't CPU bound to compare a 4 char string 2 billion times...
- carlsborg 6y ago> 342,000,000 > bytes written in one second High end NVMe ssd can probably do 3x to 10x better than ~300MB/second sequential write.
- slau 6y agoIndeed. I have 2TB of storage that is only 5 times slower than my 32GB of main memory (4GB/s vs 20GB/s).
- bane 6y agoSomething to think about, back in the 80s, when computers were millions of times slower than today, they were still considered so fast that it was worth sacrificing most of the performance by letting people work in an interpreted language BASIC -- and people were still able to be productive and do real work with them.
- userbinator 6y agoMillions, no. Thousands, yes. Keep in mind that those 80s interpreted languages still have less overhead than the HLLs of today.
- bane 6y agoNo, a typical desktop computer today is millions of times faster than a typical 1980s 8-bit computer. A Commodore 64 ran a 6510 at ~1Mhz (depending on NTSC or PAL). It was a single core CPU with no pipelining or superscaler features and took multiple cycles to complete a single operation putting it's performance in the hundreds of thousands of operations (of any kind) per second. The Playstation 4, a consumer-grade entertainment device provides around 8TFLOPs of performance. Just a CPU, like an AMD 3990x is rated at 2.3 million MIPS while the 6502 at 1Mhz is rated at less than .430 MIPS.
- coronadisaster 6y ago"A newer computer won't make your code run 1000x faster :) " unless it is quantum?
- lulzx 6y agoIt's a critical problem, there are three key areas to prioritize to continue to deliver computing speed-ups: - better software - new algorithms - more streamlined hardware The performance benefits from miniaturization have been so great that, for decades, programmers have been able to prioritize making the writing of code easier rather than making the code itself run faster. The inefficiency that this tendency introduces has been acceptable, because faster computer chips have always been able to pick up the slack. Now, If we want to harness the full potential of these technologies, we must change our approach to computing. The researchers recommend techniques like parallelizing code. The multicore technology has enabled complex tasks to be completed thousands of times faster and in a much more energy-efficient way. we will have to deliver performance the hard way. For algorithms, the team suggests a three-pronged approach that includes exploring new problem areas, addressing concerns about how algorithms scale, and tailoring them to better take advantage of modern hardware. ..many others will need to take these issues seriously if they want to stay competitive. Performance growth will require new tools, programming languages and hardware to facilitate more and better performance engineering computer scientists being better educated about how we can make software, algorithms and hardware work together, instead of putting them in different silos.
- entha_saava 6y agoAm I the only one who dislikes all this parallelism hype? For data analysis and batch jobs on large amounts of data it would be great. Other consumer oriented applications should run on single core. It hurts when people dismiss otherwise perfectly fine languages like OCaml saying "No multicore" as if majority of tasks need some kind of parallelism.. JS and Python don't do multicore well either.