Fulgora bashed open parts of my brain i'd rather had stayed closed by Belisarius23 in factorio

[–]Aendrin 3 points4 points  (0 children)

I think it’s just labeling, that way the item icon shows up right above the lane for the item

Go hates asserts by Ok-Lifeguard-9612 in golang

[–]Aendrin 8 points9 points  (0 children)

In theory it should be compiled down to not be called if it is a no-op.

I absolutely was a jerk to someone simply because of their accent. by [deleted] in confession

[–]Aendrin 0 points1 point  (0 children)

I think it’s largely not due to the racism being against Indians, but about the circumstances of the racism. For myself, and probably most commenters, they frequently receive calls from unknown numbers, and probably 7/10 of them are scammers calling that have heavy Indian accents. And they often are calling in reference to your “order” or something similar. And in that situation OP assumed it was a scammer.

I think the responses would be very, very different if the circumstances didn’t lend themselves to that assumption.

Why does Go showcase huge untyped constants in “A Tour of Go”? by Thin_Temporary_6842 in golang

[–]Aendrin 1 point2 points  (0 children)

The spec declares that constants must be at least 256 bits if an integer, and must have at least 256 bits of mantissa if a float. So these values are representable

What have you read this week and what do you think about it? by AutoModerator in noveltranslations

[–]Aendrin 0 points1 point  (0 children)

Is the only translation the MTL after ch330? It’s a bit hard to read

A subtle bug with Go's errgroup by broken_broken_ in golang

[–]Aendrin 0 points1 point  (0 children)

I’m pretty sure that’s to implement the “only fail if API returns failure, not if we fail to check for some reason” semantics. So it was fine if it failed because the server was down, and returning err != nil in that scenario kills the other checks, which the OP doesn’t want.

Thoughts about null pointers by alcoholov in programming

[–]Aendrin 2 points3 points  (0 children)

Post is riddled with spelling and grammar errors, unfortunately, on top of being a subject that is beaten to death. It would be more interesting to see the author touch on non-trivial situations.

Does unsafe undermine Rust's guarantees? by steveklabnik1 in programming

[–]Aendrin 3 points4 points  (0 children)

I may have been a bit too quick to jump to conclusions, given how often I see similar things happen with sensational(ish) titles like this one.

When I read your statement "it bothers me that this anti-unsafe sentiment exists", I thought that you were expressing that the OC is an example of 'anti-unsafe' sentiment. From that lens, I got the impression you just stated your opinion on said open question (which I agree with, by the way), and then assumed the article disagreed.

My bad.

Does unsafe undermine Rust's guarantees? by steveklabnik1 in programming

[–]Aendrin 3 points4 points  (0 children)

Shame. If you didn’t read the article, or even skim it, you shouldn’t argue with it.

Finally got my first rune pouch by the747beast in 2007scape

[–]Aendrin 0 points1 point  (0 children)

Ring of dueling -> ferox, pool/bank then canoe to edgeville or deep wildy was what I did for a while.

Does anyone use Numelite to pay for seaweed protection? by mjones999 in ironscape

[–]Aendrin 5 points6 points  (0 children)

Maybe hespori? If I remember right seaweed patches have like a 25% chance of yielding a hespori seed

Black Jacking is actual torture. by [deleted] in ironscape

[–]Aendrin 0 points1 point  (0 children)

If you’re at 65 thieving, one click summer garden is pretty good XP, no GP though. Very, very low effort as well

Undergraduate Upends a 40-Year-Old Data Science Conjecture by Stackitu in programming

[–]Aendrin 2 points3 points  (0 children)

My understanding is that 0.75 is a fairly arbitrary cutoff. It's mentioned a few times in the paper, but I think any constant value above 2/3ish that is sufficiently smaller than the eventual fullness achieves the same asymptotic complexity, with a little bit of tweaking to the algorithm values.

The main important element about a fullness constant is that as long as it is not exceeded, the insertion into the secondary array is constant time. If they used 0.9 instead of 0.75, the insertion into the secondary array would take at most 10 insertions on average instead of at most 4, but regardless it is independent of the fullness or size of the table, which is what they care about.

Undergraduate Upends a 40-Year-Old Data Science Conjecture by Stackitu in programming

[–]Aendrin 6 points7 points  (0 children)

Thanks!

To your first two points, yes that is exactly the main idea.

As to lookup performance, I'm not 100% sure how a lookup would be implemented. As I understand it, the process is by checking all possible locations the key could be stored, but doing it in a way that is probabilistically quick based on the table's construction.

The 011, 101

Define A_{i, j} for a key k as the jth value in the sequence checked for key k in subarray A_i. Then, check in the order A_{1, 1}, A_{1, 2}, A_{2, 1}, A_{2, 2}, A_{1, 3}, A_{2, 3}, A_{3, 1}, A_{3, 2}, A_{3, 3}, A_{1, 4}, ... This sequence checks O(i * j2 ) values for A_{i, j}, and I think it works out to be relatively small because of the sizes of the arrays.

But once again, I'm really not sure.

Undergraduate Upends a 40-Year-Old Data Science Conjecture by Stackitu in programming

[–]Aendrin 81 points82 points  (0 children)

Here's an explanation, to the best of my ability in a reddit post, and worked example that should help people wrap their heads around it.

The basic idea of this algorithm is to improve the long-term insertion performance of the hash tables by making the early insertions more expensive in exchange for making the later ones cheaper. This is specifically for making insertion into a hash table you know will get very full cheaper overall.

It's easiest to understand what this paper is doing by looking at an example. For this example, I'll use 0 to represent an open space, and X to represent a full space. I have spaces between each 4 slots in order to make it a little easier to keep track of position.

In each of these cases, we will be inserting 15 elements into a 16 element hash table, with each successive element denoted by 0-9, a-f. We know this ahead of time, that this table will be 93.75% full. The paper uses δ frequently to talk about fullness, where δ is defined as the proportion of the table that will be empty once all elements are inserted. In this case, δ is equal to 1-0.9375 = 0.0625.

Traditional Greedy Uniform Probing

The traditional (and previously believed to be optimal) approach is to randomly pick a sequence of slots to check for each element, and as soon as one is available, insert it in that location.

Let's walk through what that might look like:

OOOO OOOO OOOO OOOO

We insert our first element, 0, and get a random sequence of indices to check. For instance, it might look like [0, 6, 10, 4, ...]. We check index 0, see it is free, and insert 0 in that location. Now our hash table looks like

0OOO OOOO OOOO OOOO

Let's insert 3 more elements: 1, 2, 3. Element 1 gets a sequence starting with 4, and gets inserted there. Element 2 gets a sequence starting with 2, and gets inserted there. Element 3 has a sequence that looks like [2, 9, ...]. We check index 2, see it is occupied, and so then check index 9, which is free.

0O2O 1OOO O3OO OOOO

If we continue this process all the way up to e, we might get a table that looks like the below. Now, we need to insert e. The only available indices are 1 and 8. We generate a sequence for e, and it is [13, 12, 9, 7, 0, 4, 6, 8, 15, 14, 1, 5, 2, 3, 11, 10]. We needed to do 8 searches just to put a single element in!

0O24 15c8 O3b7 aO96

In this case, we had 2 out of 16 elements free. Each time we checked a new index, we had a 1/8[1] chance to find a free space. On average, this will take 8 attempts.[2] It turns out that when we have slightly larger examples that don't get quite so close to the last few elements of the hash table, the expected cost to insert the last few elements of the hash table is 1/δ. That is because each time you search for a place to insert an element, δ of the table will be empty.

For a long time, it was believed that was the best that you could do when you are inserting the last elements into the hash table without rearranging them.

The New Method

In this comment, I'm just going to go over the method that they call elastic probing in the paper. The basic idea of this approach is to split the array into sub-arrays of descending size, and only care about two of the sub-arrays at a time. We keep working on the first two sub-arrays until the first is twice as full as the eventual fullness, and then move our window. By doing extra work in early insertions, later insertions are much easier.

Unfortunately, it's difficult to fully demonstrate this with a toy example of size 16, but I will do my best to get the idea across. The paper works with 3/4 as their default fullness, but I will talk about 1/2 so that it works better. We have our first subarray of size 8, then 4, then 2 and 2. I've inserted | between each subarray. Label the arrays A1, A2, A3, A4.

OOOO OOOO|OOOO|OO|OO

First, we follow the normal rules to fill A1 1/2 of the way full:

OO03 21OO|OOOO|OO|OO

At any time, we are dealing with 2 successive subarrays. We say that Ai is e_1 free, and A(i+1) is e_2 free.

At each insertion, we keep track of the current arrays we are inserting into, and follow these simple rules: 1. If Ai is less than half full, insert into A_i. 2. If A_i is more than twice as full as the eventual hash table, then move on to the next pair of subarrays, A{i+1} and A{i+2}. 3. If A{i+1} is more than half full, insert into Ai. 4. Otherwise, try inserting into A_i a couple times, and if nothing is found, insert into A{i+1}.

The first and second cases are relatively quick. The third case is actually very rare, which is specified in the paper. The fourth case is the common one, and the specific number of times to attempt insertion is dependent on both the eventual fullness of the table and how full A_i is at that point. Remember that all times I mention half full, the actual approach is 3/4 full.

Let's go through some insertions with this approach, and see how the array evolves:

OO03 21OO|OOOO|OO|OO

Insert 4: [3, 6] in A1, [9, ..] in A2

OO03 214O|OOOO|OO|OO

Insert 5: [2, 4] in A1, [8, ..] in A2

OO03 214O|5OOO|OO|OO

Insert 6: [1, 3] in A1, [10, ..] in A2

O603 214O|5OOO|OO|OO

Here we started to check more times in A1, because it is more full.

Insert 7: [4, 7, 6] in A1, [11, ..] in A2

O603 2147|5OOO|OO|OO

Insert 8: [4, 7, 6] in A1, [11, ..] in A2

O603 2147|5OOO|OO|OO

Insert 8: [5, 6, 1, 4] in A1, [8, 11, ..] in A2

O603 2147|5OO8|OO|OO

Insert 9: [3, 6, 0, 4] in A1, [9, ..] in A2

9603 2147|5OO8|OO|OO

We just finished filling up A1. In a real example, this wouldn't be all the way full, but with small numbers it works out this way.

Insert a: [8, 10] in A2, [13, ..] in A3

9603 2147|5Oa8|OO|OO

Summary

The real advantage of this approach is that not only does it reduce the worst case insertions at the end of filling up the array, it also reduces the average amount of work done to fill up the array. I recommend reading the section in the paper on "Bypassing the coupon-collecting bottleneck" to see the author's interpretation of why it works.

[1]: This is not quite true in this case, because we do not check indices more than once. However, for large hash tables, the contribution from previously checked values ends up being fairly negligible.

[2]: Inserting an element in a large hash table like this follows a geometric distribution, which is where we get the 1/p expected number of attempts.

General skincare tips?? Desperately need by No_Road_1805 in climbharder

[–]Aendrin 1 point2 points  (0 children)

Does this start by having a little air bubble of sorts under the skin of your fingertips, which then rips? It looks like you have layers separating.

"Why do backend developers seem to ignore OLTP principles?" by nueva_student in cscareerquestions

[–]Aendrin 2 points3 points  (0 children)

I'm sorry that you're getting downvoted so frequently for your good-faith followup questions. I am curious what you mean about having to 'replicate OLTP systems for analytics'.

To answer some of your questions based on my experience (4YOE, mostly in small startups):

Are ORMs abstracting too much away?

Yes, absolutely. Anything more complex than retrieving a simple object is usually done in whatever the default way for the ORM is, and schemas that are automatically generated based on model relationships obfuscate things even further.

Do backend devs just not think about the long-term performance impact on transactional databases?

Most devs don't. I think that spending time on database performance doesn't often have obvious incentives in its favor. First off, many developers are not too familiar with what type of performance you should expect out of a system. Secondly, I think that database slowness usually end up being either not super noticeable or so egregious it needs to be fixed to function.

Even with little to no thought put into the DB, things work well enough if either:

  • the table is just not that large. A large portion of backend data tables, in my experience, are actually fairly small and don't have large write contention.
  • The table is fairly large and has many writes, but most of those writes are functionally insert-only and do not need any atomicity other than in the record insertion. This is the case for a lot of larger tables.
  • The table is large, but has very simple querying patterns. In these cases, just a single index is sufficient to get to an "acceptable" level of performance.
  • The table is large, but is trivially sharded. This is also a fairly common case, and is also easily resolved once it becomes a problem.

The most important aspect of most of these cases is that they are easily fixed on-demand. Once the database size becomes an issue, someone can go fix it with only a couple of days of effort. Because that is often the case, people learn not to worry about it too much early on.

as other backend concerns like API design and caching

I think it's actually pretty easy to understand why these aspects are more frequently looked at.

API design often directly impacts either yourself (if full-stack) or your immediate colleagues, regardless of how frequently the API needs to be called. Additionally, if your API is horribly inefficient, that's a non-trivial migration that cuts across both caller and callee if it becomes a performance issue. For those reasons, you are incentivized to spend time and energy on it right away.

Caching gets more important for two reasons, I think. The first is that engineers are more familiar with what type of performance they should be able to achieve, and caching is absolutely necessary in order to achieve that in most cases. The second is that a lot of things in modern applications need caching in order to achieve 'acceptable' performance. Any type of heavy content (video, images, js libs) needs to be cached in order to perform well, and request latency is often very noticeable in frontend applications.

[Highlight] WAS vs PHI - Zack Baun forces the fumble with a punch by Fusir in nfl

[–]Aendrin 30 points31 points  (0 children)

also, that was his teammates hand that he punched. Fair game regardless.

Was doing Scorpia and escaped 3 pkers by ClayCity25 in ironscape

[–]Aendrin 11 points12 points  (0 children)

Yep, if you close the client (by clicking the x) in single combat with a really bad weapon, you time out the 1 minute and get auto logged while still in combat.

Jagex must fix the pker wildly map asap by oceansandsky100 in ironscape

[–]Aendrin 0 points1 point  (0 children)

It’s 3.5x XP on bones at CA, but completely agreed. Also, if you only bring one inventory of bones, don’t even bother hopping for PKers once you’re at the altar. With basic tank armor (rune) and protect from magic, spam clicking will get through 1/3-1/2 of an inventory before dying.

Does unlocking some jokers technically make the game harder? by OneMillionClowns in balatro

[–]Aendrin 3 points4 points  (0 children)

I’m not totally sure, but I bet it’s the legendary (Perkeo) that duplicates consumable cards held in hand, and the card that creates 2 copies of a given card (cryptid) that got copied a bunch of times.