<story><title>Ask HN: What&apos;s your proudest hack?</title><text>I saw this question being asked on here years ago with few but interesting answers. I&amp;#x27;d imagine that a lot of you still have some pretty interesting stories to tell about some crafty workarounds.</text></story><parent_chain><item><author>ww520</author><text>In my first job I work on a database product in development that leaked memory slowly, leading to crashes after hours of usage. The software was written in C and there were no tools like Purify or Valgrind back then to deal with memory problem. It was a vexing problem that got punted until release time, when it became a show stopper.&lt;p&gt;I looked into the problem and found that the memory allocation used malloc and free.  I then defined macros for malloc and free in a common header to call my_malloc and my_free functions with the standard __FILE__ and __LINE__ macros passed in as parameters.  Re-compiled the whole program with the macros, which redirected every call of malloc and free to my functions.  My functions logged all the calls with the allocated memory pointer, the filename, and the line number.  Once I collected enough log data from test runs, I sorted the lines in the log file by the memory pointer address.  Every pointer address should come in pair, one from the malloc() and one from the free().  The odd number pointer addresses are the ones with missing free().  And I got their filename and line number right there.</text></item></parent_chain><comment><author>josephg</author><text>Hah! A few years ago I did something similar.&lt;p&gt;I was in the process of porting some C code (a physics engine) to javascript. After porting the code I benchmarked it - and, no surprises - it was waay slower than the original C code.&lt;p&gt;One reason C is faster than javascript is that C structs get &amp;quot;inlined&amp;quot; into the containing object. For example, in C struct Body { vec2 pos; vec2 velocity; } would just be 1 object. But the equivalent javascript code would allocate 3 objects instead.&lt;p&gt;I inlined vec2 (replacing it with pos_x, pos_y, etc) and performance got a lot better. But I was curious what other structs were thrashing the garbage collector. So I added a call into all my constructors which generated a stack trace (new Error().stack), and used the stack trace as the key in a javascript object - with the value being the number of times that stack trace was seen.&lt;p&gt;After sorting and printing the result, I had a hit list of the hottest stack traces which were thrashing V8&amp;#x27;s garbage collector. I fixed all the worst call sites and by the time I was done performance improved by about 3x or so!</text></comment>
<story><title>Ask HN: What&apos;s your proudest hack?</title><text>I saw this question being asked on here years ago with few but interesting answers. I&amp;#x27;d imagine that a lot of you still have some pretty interesting stories to tell about some crafty workarounds.</text></story><parent_chain><item><author>ww520</author><text>In my first job I work on a database product in development that leaked memory slowly, leading to crashes after hours of usage. The software was written in C and there were no tools like Purify or Valgrind back then to deal with memory problem. It was a vexing problem that got punted until release time, when it became a show stopper.&lt;p&gt;I looked into the problem and found that the memory allocation used malloc and free.  I then defined macros for malloc and free in a common header to call my_malloc and my_free functions with the standard __FILE__ and __LINE__ macros passed in as parameters.  Re-compiled the whole program with the macros, which redirected every call of malloc and free to my functions.  My functions logged all the calls with the allocated memory pointer, the filename, and the line number.  Once I collected enough log data from test runs, I sorted the lines in the log file by the memory pointer address.  Every pointer address should come in pair, one from the malloc() and one from the free().  The odd number pointer addresses are the ones with missing free().  And I got their filename and line number right there.</text></item></parent_chain><comment><author>bane</author><text>You know, that&amp;#x27;s surprisingly an elegant hack. I&amp;#x27;m sure it&amp;#x27;s obvious to some folks, but for some reason I never came up with it during my old C programming days.</text></comment>