147

Instead of speculating about what may or may not happen, let's just look, shall we? I'll have to use C++ since I don't have a C# compiler handy (though see the C# example from VisualMelon), but I'm sure the same principles apply regardless. We'll include the two alternatives you encountered in the interview. We'll also include a version that uses abs as ...


108

If I need to use a piece of memory throughout the lifespan of my program, is it really necessary to free it right before program termination? It is not mandatory, but it can have benefits (as well as some drawbacks). If the program allocates memory once during its execution time, and would otherwise never release it until the process ends, it may be a ...


66

To answer the stated question: When to optimize for memory vs performance speed for a method? There are two things you have to establish: What is limiting your application? Where can I reclaim the most of that resource? In order to answer the first question, you have to know what the performance requirements for your application are. If there are no ...


45

"this would reduce memory" - em, no. Even if this would be true (which, for any decent compiler is not), the difference would most probably be negligible for any real world situation. However, I would recommend to use method A* (method A with a slight change): private bool IsSumInRange(int a, int b) { int sum = a + b; if (sum > 1000 || sum < ...


35

The short answer is that cases seem to be few and far between. There are probably a few though. One would be when you need to store a small number of large objects -- especially, objects that are so large that it's impractical to allocate space for even a few extra of them. There's basically no way to stop a vector or deque from allocating space for extra ...


33

You can do better than both of those with return (abs(a + b) > 1000); Most processors (and hence compilers) can do abs() in a single operation. You not only have fewer sums, but also fewer comparisons, which are generally more computationally expensive. It also removes the branching, which is much worse on most processors because it stops pipelining ...


31

This is a valid concern. While I have not measured the memory usage of Redux applications, I think that before committing to use Redux (or any other framework for that matter) you should create stress tests that emulate the data amounts, change frequency, and computation intensity of the application you are going to build. Use these stress tests before ...


29

It depends on your operating system. On Windows, the typical maximum size for a stack is 1MB, whereas it is 8MB on a typical modern Linux, although those values are adjustable in various ways. If the sum of your stack variables (including low-level overhead such as return addresses, stack-based arguments, return value placeholders and alignment bytes) in the ...


28

According to Bjarne Stroustrup himself, vectors should always be the default collection for sequences of data. You can choose the list if you want to optimize for insertion and deletion of elements, but normally you shouldn't. The costs of the list is slow traversal and memory usage. He talks about this in this presentation. At about 0:44 he talks about ...


16

When is it appropriate to use Method A vs. Method B, and vice versa? Hardware is cheap; programmers are expensive. So the cost of the time you two wasted on this question is probably far worse than either answer. Regardless, most modern compilers would find a way to optimize the local variable into a register (instead of allocating stack space), so the ...


15

The only valid answer is vague: "too much is when the stack overflows." Unless you are in complete control over the implementation of every line of code between the program's entry point and the function in question, you can make no assumptions about how much stack is available. You cannot, for example, guarantee that calling this function will never cause ...


15

Yes, memory alignment still matters. Some processors actually can't perform reads on non-aligned addresses. If you're running on such hardware, and you store your integers non-aligned, you're likely to have to read them with two instructions followed by some more instructions to get the various bytes into the right places so you can actually use it. So ...


15

From the memory-allocation point-of-view, you're right. A pointer variable on a 64-bit architecture occupies 8 bytes, no matter what type of pointer it is. But the C compiler needs to know more about a variable than its size. An analogy: long and float typically both need 4 bytes (so why have different types???), but you surely tell the compiler which one ...


14

The only place where I usually use lists is where I need to erase elements and not invalidate iterators. std::vector invalidates all iterators on insert and erase. std::list guarantees that iterators to existing elements are still valid after insert or delete.


14

But I cannot get my head around to how the boost library does this. The boost interprocess mechanism has three necessary components to work: memory-mapped file: a memory-mapped file needs to be created and passed to a boost.interprocess allocator. This allocator will take chunks of the file and use them as if they were returned by a std::allocator, with ...


13

Look at it at the other way, from the system perspective. You have a giant pool of free memory (free ram memory) where different programs can make use of. But all of their used resources should be returned sooner or later, or at least being used the entire time. When you no longer need it you should return it to the pool of free memory. Applications that ...


12

Well you're right about something being wrong. But I highly doubt worrying about memory usage is going to fix it. Unless you can point to some real world data that shows you have a memory problem at the scale of these references, I wouldn't worry about it. This smacks of premature optimization. Now that doesn't mean there aren't problems here. The master ...


12

private methods can never be overridden, whereas protected and public methods can be overridden. As a consequence of this, the underlying runtime knows that for private methods: There is no need to place them in the method table It can invoke them using non-virtual dispatching By contrast, protected and public methods are most likely placed into the ...


12

The internet. When you have multiple computers networked together there is no such thing as "the word size". Every computer has its own idea how big it's bus is. But they all agree on bytes (even if they can't agree on byte order). So we keep making bytes addressable. It helps with compatibility issues. It's a carry over from the days of 8 bit computing ...


11

Having more variables than registers isn't necessarily a problem. If a variable's value isn't used after a certain point in the function, the compiler can use that register for another variable. Even when there's more variables in use at a certain point than there are registers, the compiler will probably do a better job of figuring out the order in which ...


11

Freeing memory at the end of a programs run is just a waste of CPU time. It's like tidying a house before nuking it from orbit. However sometimes what was a short running program can turn into part of a much longer running one. Then freeing stuff becomes necessary. If this wasn't thought about to at least some extent then it can involve substantial ...


11

Yes both alignment and arrangement of your data can make a big difference in performance, not just a few percent but few to many hundreds of a percent. Take this loop, two instructions matter if you run enough loops. .globl ASMDELAY ASMDELAY: subs r0,r0,#1 bne ASMDELAY bx lr With and without cache, and with alignment with and without cache ...


11

I would optimize for readability. Method X: private bool IsSumInRange(int number1, int number2) { return IsValueInRange(number1+number2, -1000, 1000); } private bool IsValueInRange(int Value, int Lowerbound, int Upperbound) { return (Value >= Lowerbound && Value <= Upperbound); } Small methods that do just 1 thing but are easy to ...


9

The process of sharing strings in this manner is called String Interning, and yes, Javascript does it. The way in which string interning is accomplished in Javascript is an implementation detail, and it varies between different Javascript implementations. From a performance perspective, you probably shouldn't be worrying about this unless it becomes a ...


9

In general, asking the garbage collector to collect is more of a recommendation than an actual order. You should not do this at all. The garbage collector will properly respond to memory pressure. And like every optimization, measure first. Once you actually have GC slowness, then worry about fixing it.


9

I was wondering what exactly memory cleaner software do? In the best case, they do absolutely nothing. If you're lucky. Sometimes, they will actually free up RAM by deleting caches or forcing processes out of RAM. The thing is: free RAM is actually bad. RAM is much faster than hard disk, and it is also much more expensive. So, you should be using as much ...


8

Unfortunately, there's really no good way to answer the question "how much RAM is my program using?" or "how close am I to hitting the OutOfMemoryException wall?", for a number of reasons. It's a lot more complicated than it looks like it should be. One thing you might want to do, though, is make sure that you're not holding on to the input data ...


8

The only thing I'm conscious is that I have to make sure I actually have 1KB of stack free when entering this function. Yes, and that is a strong constraint. You'll better be sure statically than you do have such a large space available on the stack. If the code is small, if you are using a recent GCC to compile your code, see this. BTW, some cheap ...


8

You have some very good answers on the topic here Generally, your struct is probably too big for the CPU cache, so probably parts of it end up in L2 cache or in RAM memory, which is significantly slower than L1 cache, hence performance issues. You might want to try and do some profiling and find out exactly what is going on. If you do, I would very much ...


8

The C Standard requires that the implementation must be able to read and write single bytes. If you have an array char a[100] and one thread increases a[0] by 1, while another thread increases a[1] by 1, it is required that the implementation doesn't introduce any race condition. This is the case even if your code runs on a server with two sockets (that is ...


Only top voted, non community-wiki answers of a minimum length are eligible