7 ms·
Interpreted languages can have pretty high memory overhead. Let's say we have a page in python or php or ruby or whatever, and it needs to fetch 1,000 rows from
by snissn 10y ago
Interpreted languages can have pretty high memory overhead. Let's say we have a page in python or php or ruby or whatever, and it needs to fetch 1,000 rows from a database (100 things here, 20 things there, whatever). Each row in the database can be turned into an object several times, one from the model, one from the controller, one for the template/view. On top of that, each object is a composite key/value object of let's make up 10 fields, so that's 20 PyObjects or whatever. In Python an empty PyDict uses up 280 bytes. sys.getsizeof({}). so 1,000321*280 = 17.64MB. That's just a back of the envelope theoretical minimum, include bad coding (for another few multiples), pages that require more data (analytics/stats/reporting pages), and concurrency and you can get up there!
- userbinator 10y agoNeeding to fetch 1k rows from a database is different from needing to keep all that data in memory, however. Several years ago I had to return 1M rows from a database to the client with a PHP script, and it needed less than the 16MB (yes, sixteen megabytes) that the environment of the time was configured with as a memory limit. 1G rows would not have consumed any more memory either, because at any one time the script never needed to keep more than around a dozen cells in memory, each not more than a few KB. Read a cell from the database, process it, output the result and move onto the next one. Essentially O(1) space regardless of how much data there is. Or are you saying that web applications are now written to retain all that data in memory despite the fact that it's not actually needed, and such stupid algorithms are actually considered acceptable? I think that's pretty ridiculous. The whole idea of database concepts like cursors is that you shouldn't be required to hold the entire resultset in memory, because it might not fit.
- wahern 10y agoThis should be even easier these days. Async I/O platforms like Node.js mean you don't have to worry about a process sticking around while it trickles data to a client. And web frameworks make it easier to deliver datasets asynchronously as JSON to the browser. Generally, there's less excuse to buffer everything server-side, e.g. to generate a full page. I think the reliance on large frameworks and external libraries is the problem here because they don't generally compose in a way that permits optimizing data flow. That and the usual reduction in average skill required to work in this area.[1] People will spend an eternity arguing over which is the faster hash table algorithm, but have no eye or concern for optimizing the large details even though the relative improvements in performance and scale could be orders of magnitude better and conceptually much easier to implement. This is why higher-level languages need stackful coroutines, not just promises or async/await. Stackful coroutines make it much easier to implement and compose space-efficient iterators, for example, in the context of uncooperative libraries, and to do so performantly. People are so obsessed with async I/O they've forgotten why it's so darned useful and how you want to best leverage it. They keep going down the rabbit hole of callbacks and actors, but the fact of the matter is that those things are too complex to use pervasively in the pipeline of individual requests. They're the modern equivalent of gotos--easy to use and abuse, but not what you want to use as an abstraction for tying together different pieces of code because they have poor locality of context, require leaking too much detail at the interface boundaries, are more difficult to refactor, and generally require a high cognitive burden. We want to be lowering cognitive load and other constraints! [1] To be fair, I was one of those less-skilled newcomers back in the late 90s, abusing the newer technologies and frustrating the grey beards.
- kalleboo 10y ago> Or are you saying that web applications are now written to retain all that data in memory despite the fact that it's not actually needed Even the standard PHP MySQL API (mysqli) defaults to MYSQLI_STORE_RESULT which buffers all the results in memory. You have to specify MYSQLI_USE_RESULT to get streaming results.
- byroot 10y agoAnd what do you do if an error happen in the middle of your iteration while the server already answered with 200 OK and sent half of the response? Your only option in those case with PHP is to truncate the response which IMO is the ridiculous choice here...