HN user

simscitizen

417 karma
Posts1
Comments108
View on HN

I know this type of approach was rejected at the beginning, but you can also just ask CoreGraphics to use the GPU for 2D rendering (and I'm sure there are equivalent paths in e.g. Skia or Cairo).

On macOS/iOS, the easiest way would probably be to set the drawsAsynchronously property on a CALayer. Then, all CoreGraphics operations on the context passed back to the layer via drawInContext: will be GPU accelerated.

Lastly, there are some pretty sharp edges to this API, so definitely don't go flipping it on for every layer/view in your view hierarchy.

I'm not sure if this works well for more demanding games, but recently I wanted to let my kid play Number Munchers and Oregon Trail and just built a webpage for those games using js-dos. It worked well enough for those games.

There's already a popular OS that disables overcommit by default (Windows). The problem with this is that disallowing overcommit (especially with software that doesn't expect that) can mean you don't get anywhere close to actually using all the RAM that's installed on your system.

Copying the file likely forces the creation of a new one with no or lower filesystem fragmentation (e.g. a 1MB file probably gets assigned to 1MB of consecutive FS blocks). Then those FS blocks likely get assigned to flash dies in a way that makes sense (i.e. the FS blocks are evenly distributed across flash dies). This can improve I/O perf by some constant factor. See https://www.usenix.org/system/files/fast24-jun.pdf for instance for more explanation.

I would say that the much more common degradation is caused by write amplification due to a nearly full flash drive (or a flash drive that appears nearly full to the FTL because the system doesn't implement some TRIM-like mechanism to tell the FTL about free blocks). This generally leads to systemwide slowdown though rather than slowdown accessing just one particular file.

This was especially prevalent on some older Android devices which didn't bother to implement TRIM or an equivalent feature (which even affected the Google devices, like the Nexus 7).

Not really something anyone can change at this point, given that the entire web API presumes an execution model where everything logically happens on the main thread (and code can and does expect to observe those state changes synchronously).

I agree, all of these rules aren't the right way to teach about how to reason about this. All of the perf properties described should fall out of the understanding that both tables and indices in SQLite are B-trees. B-trees have the following properties:

- can look up a key or key prefix in O(log N) time ("seek a cursor" in DB parlance, or maybe "find/find prefix and return an iterator" for regular programmers)

- can iterate to next row in amortized O(1) time ("advance a cursor" in DB parlance, or maybe "advance an iterator" for regular programmers). Note that unordered data structures like hash maps don't have this property. So the mental model has to start with thinking that tables/indices are ordered data structures or you're already lost.

A table is a b+tree where the key is the rowid and the value is the row (well, except for WITHOUT ROWID tables).

An index is a b-tree where the key is the indexed column(s) and the value is a rowid.

And SQLite generally only does simple nested loop joins. No hash joins etc. Just the most obvious joining that you could do if you yourself wrote database-like logic using ordered data structures with the same perf properties e.g. std::map.

From this it ought to be pretty obvious why column order in an index matters, etc.

iPhone dumbphone 11 months ago

That’s exactly what he meant by using Focus Modes, which is the iOS feature that lets you do just that.

If you type the name of the person, it should allow you to create a filter for "Messages with: Person". It should also pop up a filter bubble for photos. From there I think you can type in some query and it should do a query on the photos via text. I don't think you can add your date filter though.

Second way would be to open that conversation view, click on the contact icon at the top of the view, which should then bring you to a details page that lists a bunch of metadata and settings about the conversation (e.g. participants, hide alerts, ...). One of the sections shows all photos from that conversation. Browse that until you find the one you care about.

Oh I've debugged this before. Native memory allocator had a scavenge function which suspended all other threads. Managed language runtime had a stop the world phase which suspended all mutator threads. They ran at about the same time and ended up suspending each other. To fix this you need to enforce some sort of hierarchy or mutual exclusion for suspension requests.

Why you should never suspend a thread in your own process.

This sounds like a good general princple but suspending threads in your own process is kind of necessary for e.g. many GC algorithms. Now imagine multiple of those runtimes running in the same process.

It is insane that we have to dedicate multiple gigabytes of RAM, have CPUs 1000x faster than we had back with Netscape Navigator

Webpages are applications. Browsers are application runtimes. The main culprit driving high memory usage is not the runtime, but the application.

Pretty sure it’s just scheduled CPU time / wall clock time. If you have multiple cores then scheduled CPU time can be greater than wall clock time.

Also scheduled CPU time doesn’t take in to account frequency scaling or core type as explained in the article. Just how much time the OS scheduler has allocated to the core to run tasks.

That’s not the current documentation, as evidenced by the “archive” in the URL.

If you want to stay at a lower level the recommendation these days is to use Network.framework. If you want something higher level then use CFNetwork (probably through the classes exported by Foundation like NSURLSession).

How does this work exactly? Is every log line a separate transaction in autocommit mode? Because I don't see any begin/commit statements in this codebase so far...

The main ones were www which contained most of the PHP code and fbcode which contained most of the other backend services. There were actually separate repos for the mobile apps also.

Peaks don't matter, they just correspond to the depth of the call stack.

Probably the simplest way to use the flame graph is work from the bottom of the flamegraph and walk upwards until you find something interesting you optimize. Ideally you find something wide to optimize that makes sense. (The widest thing here is "main" which is obviously probably not the interesting thing to optimize, so you would work upwards from there.) The basic idea is that things that are wide in the flamegraph are expensive and potential things to optimize.

Where I work, we have tools that can produce diffed flamegraphs which can be really useful in figuring out why one trace uses so much more/less CPU than another.

I do memory/CPU traces like all day every day, and I fix code all the time based on that

So I take it you understand one of the standard visualizations produced by a CPU profiling tool, e.g. it takes a call stack sample every millisecond. The x-axis is time (one sample per ms, if you have only one CPU), and the y-axis is the call stack.

Now for a flamegraph, you basically have the same visualization, but you sort the samples across the x-axis so that callstacks that start with the same prefixes are grouped together.

Incidentally, the sorting of samples across the x-axis destroys the time information which is often critical. I constantly see engineers who don't understand flamegraphs looking at the entire flamegraph of a say 3 second trace, and then trying to use that whole flamegraph to optimize a 100 ms critical path within the trace, which is totally nonsensical.

Another option on macOS/iOS is to ship just the LC_FUNCTION_STARTS section in the Mach-O binary. This is how symbolication can discover function names from system libraries even without full debug symbols on those platforms.

All this talk about frame pointers enabled on various Linux distros and we still haven’t talked about the biggest one, which would be Android. Have they decided to compile with frame pointers yet? The last time I looked in to this many years ago, some perf folks on the Android team dismissed it as a perf regression (and also ART was already using the FP register for its own purposes).

I don’t remember if the system default was changed but the default for all databases created by Apple apps was switched to WAL mode in the iOS 4 timeframe.

The infinitely growing WAL problem is a real problem though. Often that is caused by devs accidentally leaking or abandoning a never closed read transaction. I think there’s a new wal2 mode in development to address that issue. Obviously the best solution for now is to not have such long lived readers in the first place.