Hot answers tagged

169

LibGDX is a framework mostly used for game development. In game development you usually have to do a whole lot of number crunching in real-time and any performance you can get matters. That's why game developers usually use float whenever float precision is good enough. The size of the FPU registers in the CPU is not the only thing you need to consider in ...


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 ...


126

You really can't make blanket statements about appropriate way to use all GC implementations. They vary wildly. So I'll speak to the .NET one which you originally referred to. You must know the behaviour of the GC pretty intimately to do this with any logic or reason. The only advice on collection I can give is: Never do it. If you truly know the ...


116

In the case of a CPU cache, it is faster because it's on the same die as the processor. In other words, the requested data doesn't have to be bussed over to the processor; it's already there. In the case of the cache on a hard drive, it's faster because it's in solid state memory, and not still on the rotating platters. In the case of the cache on a web ...


113

Definitely not. Accessing a memory address you didn't allocate is always a programming error. And acting on the information you get out of it produces undefined behavior, that much is accurate. I have no idea what platform the original Pac-man was written for, but I'm pretty sure it exhibited this behavior just like any other von Neumann machine. However, "...


87

Does this mean the base pointer or the stack pointer are actually moving down the memory addresses instead of going up? Why is that? Yes, the push instructions decrement the stack pointer and write to the stack, while the pop do the reverse, read from the stack and increment the stack pointer. This is somewhat historical in that for machines with limited ...


81

It didn't take 12 bytes, it only took 8. However, the default alignment for an 8 byte long int on this platform is 8 bytes. As such, the compiler needed to move the long int to an address that's divisible by 8. The "obvious" address, da54dc8c, isn't divisible by 8 hence the 12 byte gap. You should be able to test this. If you add another int prior to the ...


69

A variable is a logical construct that goes to the intent of an algorithm, whereas a memory location is a physical construct that describes the operation of a computer.  Generally speaking, in order to execute a program there is (compiler generated) mapping between the logical notion of a variable and the storage of the computer. (Even in assembly language ...


68

Sadly, nobody there elaborates on what are such cases. I'll give some examples. All in all it is rare that forcing a GC is a good idea but it can be totally worth it. This answer is from my experience with .NET and GC literature. It should generalize well to other platforms (at least those that have a significant GC). Benchmarks of various kinds. You want ...


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 ...


63

They're not quite the same. The registers are the places where the values that the CPU is actually working on are located. The CPU design is such that it is only able to actually modify or otherwise act on a value when it is in a register. So registers can work logic, whereas memory (including cache) can only hold values the CPU reads from and writes to. ...


58

What you describe, "smoothing by fives", is a finite impulse response (FIR) digital filter. Such filters are implemented with circular buffers. You keep only the last N values, you keep an index into the buffer that tells you where the oldest value is, you overwrite the current oldest value with the newest one at each step, and you step the index, ...


57

Floats use half as much memory as doubles. They may have less precision than doubles, but many applications don't require precision. They have a larger range than any similarly-sized fixed point format. Therefore, they fill a niche that needs wide ranges of numbers but does not need high precision, and where memory usage is important. I've used them for ...


49

The decimal point is not explicitly stored anywhere; that's a display issue. The following explanation is a simplification; I'm leaving out a lot of important details and my examples aren't meant to represent any real-world platform. It should give you a flavor of how floating-point values are represented in memory and the issues associated with them, ...


48

No, it does not. In C, variables have a fixed set of memory addresses to work with. If you are working on a system with 4-byte ints, and you set an int variable to 2,147,483,647 and then add 1, the variable will usually contain -2147483648. (On most systems. The behavior is actually undefined.) No other memory locations will be modified. In essence, ...


48

Backwards Compatibility This is the number one reason for keeping behavior in an already existing language/library/ISA/etc. Consider what would happen if they took floats out of Java. Libgdx (and thousands of other libraries and programs) wouldn't work. It's going to take a lot of effort to get everything updated, quite possibly years for many projects (just ...


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 < ...


40

Historically (perhaps by rewriting parts of it), it was the contrary. On the very first computers of the early 1970s (perhaps PDP-11) running a prototypical embryonic C (perhaps BCPL) there was no MMU and no memory protection (which existed on most older IBM/360 mainframes). So every byte of memory (including those handling literal strings or machine code) ...


38

It looks like you're confusing "undefined behaviour" and "segmentation fault". There is no such thing as an unhandled segfault. A segmentation fault is error handling, by definition. If you don't have an OS that detected the bad memory access and terminated the process for safety, then you don't have a segmentation fault. If anything, then, this is a ...


36

I can see a DOS programmer fiddling away and crashing the entire OS when he made a mistake. Yeah, that's pretty much what happened. On most systems that had memory maps, location 0 was marked invalid, so that null pointers could be easily detected, because that was the most common case. But there were lots of other cases, and they caused havoc. At the ...


36

For short running programs memory leaks are not as important; the OS will reclaim everything on termination, but they may cause other resources to not be released. However short running is relative, a leak can spiral out of control in a few hours or stack up for weeks unnoticed. My advice is to file a bug in the tracker with a proposed fix, if the lead ...


36

Atomic operations In addition to what others have already said, a Java-specific disadvantage of double (and long) is that assignments to 64-bit primitive types are not guaranteed to be atomic. From the Java Language Specification, Java SE 8 Edition, page 660 (emphasis added): 17.7 Non-atomic Treatment of double and long For the purposes of the Java ...


35

The C standard doesn't mandate any particular way of representing negative signed numbers. In most implementations that you are likely to encounter, negative signed integers are stored in what is called two's complement. The other major way of storing negative signed numbers is called one's complement. The two's complement of an N-bit number x is defined ...


33

It is faster because both it is closer and because it is SRAM not DRAM. SRAM is and can be considerably faster than DRAM the values are kept statically (the S in SRAM) so they don't have to be refreshed which takes away cycles. DRAM is dynamic, like tiny rechargeable batteries, you have to regularly recharge the ones so they don't drain away and become ...


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 ...


28

CPU (its memory controller specifically) can take advantage of the fact that the memory is not mutated Advantage is, this fact saves compiler from using membar instructions when data is accessed. A memory barrier, also known as a membar, memory fence or fence instruction, is a type of barrier instruction which causes a central processing unit (CPU) or ...


27

See http://blogs.msdn.com/b/ricom/archive/2005/05/10/416151.aspx and follow all of the links to see Rico Mariani vs Raymond Chen (both very competent programmers at Microsoft) dueling it out. Raymond would improve the unmanaged one, Rico would respond by optimizing the same thing in the managed ones. With essentially zero optimization effort, the managed ...


27

As a general principle, a garbage collector will collect when it runs into "memory pressure", and it's considered a good idea to not have it collect at other times because you could cause performance problems or even noticeable pauses in your program's execution. And in fact, the first point is dependent on the second: for a generational garbage collector, ...


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