Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

##Preface This review treats the code as a professional exercise rather than an academic one.

##Introduction

Your intuition about one pass versus two passes was spot on.

Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. -- Donald Knuth

You Ain't Gonna Need It

In most cases O(n log n) time complexity is highly likely to be good enough. Sorting the array first makes the logic simple.

Pseudo-Code

MyArray = Input.sort
End = MyArray.length - 1
Candidate0 = 0
Candidate1 = MyArray[End] * MyArray[0] * MyArray[1]
Candidate2 = MyArray[End] * MyArray[End - 1] * MyArray[End - 2]
Return Max(Candidate0, Candidate1, Candidate2)

Performance Concerns?

Use a profiler. It is highly unlikely that the critical performance bottleneck of an interesting piece of software is a routine running in O(n log n) time.

Take Advantage of the Platform

Making assumptions about the execution path of a Java program as if it is assembly or C is an error. The Java JIT does branch prediction with one eye on the branch predition, prefetch and cache strategies of the hardware CPU. Java's sort is tuned to the eyeballs. Many man hours have gone into optimizing it to work with the JVM's underlying optimization strategies.

Hand rolled code that branches randomly is likely to see less optimization and memory latency of cache misses could swamp the theoretical efficiency of O(n) versus O(n log n) even in a critical section. Use a profiler.

##Conclusion Your intuition was sound. Correctness and clarity should come first. Performance should come later, if at all, and then only when it actually matters. The intuition just wasn't pushed far enough.

Epilogue

If, as some programmers believe, bugs are proportional to lines of code and software maintenance is a substantial fraction of total software costsoftware maintenance is a substantial fraction of total software cost, then it stands to reason that more compact code will contain fewer bugs and cost less.

Often it is easier to read as well:

public int max_prod_three(int[] A){
    private int end = A.length;
    private int[] MySortedArray = A.sort();
    return Math.max(MySortedArray[0] * MySortedArray[1] * MySortedArray[end],
                    MySortedArray[end - 2] * MySortedArray[end - 1] * MySortedArray[end],
                    0);
}

###Afterward

Programs must be written for people to read, and only incidentally for machines to execute. -- Ableson and Sussman

##Preface This review treats the code as a professional exercise rather than an academic one.

##Introduction

Your intuition about one pass versus two passes was spot on.

Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. -- Donald Knuth

You Ain't Gonna Need It

In most cases O(n log n) time complexity is highly likely to be good enough. Sorting the array first makes the logic simple.

Pseudo-Code

MyArray = Input.sort
End = MyArray.length - 1
Candidate0 = 0
Candidate1 = MyArray[End] * MyArray[0] * MyArray[1]
Candidate2 = MyArray[End] * MyArray[End - 1] * MyArray[End - 2]
Return Max(Candidate0, Candidate1, Candidate2)

Performance Concerns?

Use a profiler. It is highly unlikely that the critical performance bottleneck of an interesting piece of software is a routine running in O(n log n) time.

Take Advantage of the Platform

Making assumptions about the execution path of a Java program as if it is assembly or C is an error. The Java JIT does branch prediction with one eye on the branch predition, prefetch and cache strategies of the hardware CPU. Java's sort is tuned to the eyeballs. Many man hours have gone into optimizing it to work with the JVM's underlying optimization strategies.

Hand rolled code that branches randomly is likely to see less optimization and memory latency of cache misses could swamp the theoretical efficiency of O(n) versus O(n log n) even in a critical section. Use a profiler.

##Conclusion Your intuition was sound. Correctness and clarity should come first. Performance should come later, if at all, and then only when it actually matters. The intuition just wasn't pushed far enough.

Epilogue

If, as some programmers believe, bugs are proportional to lines of code and software maintenance is a substantial fraction of total software cost, then it stands to reason that more compact code will contain fewer bugs and cost less.

Often it is easier to read as well:

public int max_prod_three(int[] A){
    private int end = A.length;
    private int[] MySortedArray = A.sort();
    return Math.max(MySortedArray[0] * MySortedArray[1] * MySortedArray[end],
                    MySortedArray[end - 2] * MySortedArray[end - 1] * MySortedArray[end],
                    0);
}

###Afterward

Programs must be written for people to read, and only incidentally for machines to execute. -- Ableson and Sussman

##Preface This review treats the code as a professional exercise rather than an academic one.

##Introduction

Your intuition about one pass versus two passes was spot on.

Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. -- Donald Knuth

You Ain't Gonna Need It

In most cases O(n log n) time complexity is highly likely to be good enough. Sorting the array first makes the logic simple.

Pseudo-Code

MyArray = Input.sort
End = MyArray.length - 1
Candidate0 = 0
Candidate1 = MyArray[End] * MyArray[0] * MyArray[1]
Candidate2 = MyArray[End] * MyArray[End - 1] * MyArray[End - 2]
Return Max(Candidate0, Candidate1, Candidate2)

Performance Concerns?

Use a profiler. It is highly unlikely that the critical performance bottleneck of an interesting piece of software is a routine running in O(n log n) time.

Take Advantage of the Platform

Making assumptions about the execution path of a Java program as if it is assembly or C is an error. The Java JIT does branch prediction with one eye on the branch predition, prefetch and cache strategies of the hardware CPU. Java's sort is tuned to the eyeballs. Many man hours have gone into optimizing it to work with the JVM's underlying optimization strategies.

Hand rolled code that branches randomly is likely to see less optimization and memory latency of cache misses could swamp the theoretical efficiency of O(n) versus O(n log n) even in a critical section. Use a profiler.

##Conclusion Your intuition was sound. Correctness and clarity should come first. Performance should come later, if at all, and then only when it actually matters. The intuition just wasn't pushed far enough.

Epilogue

If, as some programmers believe, bugs are proportional to lines of code and software maintenance is a substantial fraction of total software cost, then it stands to reason that more compact code will contain fewer bugs and cost less.

Often it is easier to read as well:

public int max_prod_three(int[] A){
    private int end = A.length;
    private int[] MySortedArray = A.sort();
    return Math.max(MySortedArray[0] * MySortedArray[1] * MySortedArray[end],
                    MySortedArray[end - 2] * MySortedArray[end - 1] * MySortedArray[end],
                    0);
}

###Afterward

Programs must be written for people to read, and only incidentally for machines to execute. -- Ableson and Sussman

added 914 characters in body
Source Link
ben rudgers
  • 2.7k
  • 13
  • 23

##Preface This review treats the code as a professional exercise rather than an academic one.

##Introduction

Your intuition about one pass versus two passes was spot on.

Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. -- Donald Knuth

You Ain't Gonna Need It

In most cases O(n log n) time complexity is highly likely to be good enough. Sorting the array first makes the logic simple.

Pseudo-Code

MyArray = Input.sort
End = MyArray.length - 1
Candidate0 = 0
Candidate1 = MyArray[End] * MyArray[0] * MyArray[1]
Candidate2 = MyArray[End] * MyArray[End - 1] * MyArray[End - 2]
Return Max(Candidate0, Candidate1, Candidate2)

Performance Concerns?

Use a profiler. It is highly unlikely that the critical performance bottleneck of an interesting piece of software is a routine running in O(n log n) time.

Take Advantage of the Platform

Making assumptions about the execution path of a Java program as if it is assembly or C is an error. The Java JIT does branch prediction with one eye on the branch predition, prefetch and cache strategies of the hardware CPU. Java's sort is tuned to the eyeballs. Many man hours have gone into optimizing it to work with the JVM's underlying optimization strategies.

Hand rolled code that branches randomly is likely to see less optimization and memory latency of cache misses could swamp the theoretical efficiency of O(n) versus O(n log n) even in a critical section. Use a profiler.

##Conclusion Your intuition was sound. Correctness and clarity should come first. Performance should come later, if at all, and then only when it actually matters. The intuition just wasn't pushed far enough.

Epilogue

If, as some programmers believe, bugs are proportional to lines of code and software maintenance is a substantial fraction of total software cost, then it stands to reason that more compact code will contain fewer bugs and cost less.

Often it is easier to read as well:

public int max_prod_three(int[] A){
    private int end = A.length;
    private int[] MySortedArray = A.sort();
    return Math.max(MySortedArray[0] * MySortedArray[1] * MySortedArray[end],
                    MySortedArray[end - 2] * MySortedArray[end - 1] * MySortedArray[end],
                    0);
}

###Afterward

Programs must be written for people to read, and only incidentally for machines to execute. -- Ableson and Sussman

##Preface This review treats the code as a professional exercise rather than an academic one.

##Introduction

Your intuition about one pass versus two passes was spot on.

Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. -- Donald Knuth

You Ain't Gonna Need It

In most cases O(n log n) time complexity is highly likely to be good enough. Sorting the array first makes the logic simple.

Pseudo-Code

MyArray = Input.sort
End = MyArray.length - 1
Candidate0 = 0
Candidate1 = MyArray[End] * MyArray[0] * MyArray[1]
Candidate2 = MyArray[End] * MyArray[End - 1] * MyArray[End - 2]
Return Max(Candidate0, Candidate1, Candidate2)

Performance Concerns?

Use a profiler. It is highly unlikely that the critical performance bottleneck of an interesting piece of software is a routine running in O(n log n) time.

Take Advantage of the Platform

Making assumptions about the execution path of a Java program as if it is assembly or C is an error. The Java JIT does branch prediction with one eye on the branch predition, prefetch and cache strategies of the hardware CPU. Java's sort is tuned to the eyeballs. Many man hours have gone into optimizing it to work with the JVM's underlying optimization strategies.

Hand rolled code that branches randomly is likely to see less optimization and memory latency of cache misses could swamp the theoretical efficiency of O(n) versus O(n log n) even in a critical section. Use a profiler.

##Conclusion Your intuition was sound. Correctness and clarity should come first. Performance should come later, if at all, and then only when it actually matters. The intuition just wasn't pushed far enough.

##Preface This review treats the code as a professional exercise rather than an academic one.

##Introduction

Your intuition about one pass versus two passes was spot on.

Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. -- Donald Knuth

You Ain't Gonna Need It

In most cases O(n log n) time complexity is highly likely to be good enough. Sorting the array first makes the logic simple.

Pseudo-Code

MyArray = Input.sort
End = MyArray.length - 1
Candidate0 = 0
Candidate1 = MyArray[End] * MyArray[0] * MyArray[1]
Candidate2 = MyArray[End] * MyArray[End - 1] * MyArray[End - 2]
Return Max(Candidate0, Candidate1, Candidate2)

Performance Concerns?

Use a profiler. It is highly unlikely that the critical performance bottleneck of an interesting piece of software is a routine running in O(n log n) time.

Take Advantage of the Platform

Making assumptions about the execution path of a Java program as if it is assembly or C is an error. The Java JIT does branch prediction with one eye on the branch predition, prefetch and cache strategies of the hardware CPU. Java's sort is tuned to the eyeballs. Many man hours have gone into optimizing it to work with the JVM's underlying optimization strategies.

Hand rolled code that branches randomly is likely to see less optimization and memory latency of cache misses could swamp the theoretical efficiency of O(n) versus O(n log n) even in a critical section. Use a profiler.

##Conclusion Your intuition was sound. Correctness and clarity should come first. Performance should come later, if at all, and then only when it actually matters. The intuition just wasn't pushed far enough.

Epilogue

If, as some programmers believe, bugs are proportional to lines of code and software maintenance is a substantial fraction of total software cost, then it stands to reason that more compact code will contain fewer bugs and cost less.

Often it is easier to read as well:

public int max_prod_three(int[] A){
    private int end = A.length;
    private int[] MySortedArray = A.sort();
    return Math.max(MySortedArray[0] * MySortedArray[1] * MySortedArray[end],
                    MySortedArray[end - 2] * MySortedArray[end - 1] * MySortedArray[end],
                    0);
}

###Afterward

Programs must be written for people to read, and only incidentally for machines to execute. -- Ableson and Sussman

Source Link
ben rudgers
  • 2.7k
  • 13
  • 23

##Preface This review treats the code as a professional exercise rather than an academic one.

##Introduction

Your intuition about one pass versus two passes was spot on.

Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. -- Donald Knuth

You Ain't Gonna Need It

In most cases O(n log n) time complexity is highly likely to be good enough. Sorting the array first makes the logic simple.

Pseudo-Code

MyArray = Input.sort
End = MyArray.length - 1
Candidate0 = 0
Candidate1 = MyArray[End] * MyArray[0] * MyArray[1]
Candidate2 = MyArray[End] * MyArray[End - 1] * MyArray[End - 2]
Return Max(Candidate0, Candidate1, Candidate2)

Performance Concerns?

Use a profiler. It is highly unlikely that the critical performance bottleneck of an interesting piece of software is a routine running in O(n log n) time.

Take Advantage of the Platform

Making assumptions about the execution path of a Java program as if it is assembly or C is an error. The Java JIT does branch prediction with one eye on the branch predition, prefetch and cache strategies of the hardware CPU. Java's sort is tuned to the eyeballs. Many man hours have gone into optimizing it to work with the JVM's underlying optimization strategies.

Hand rolled code that branches randomly is likely to see less optimization and memory latency of cache misses could swamp the theoretical efficiency of O(n) versus O(n log n) even in a critical section. Use a profiler.

##Conclusion Your intuition was sound. Correctness and clarity should come first. Performance should come later, if at all, and then only when it actually matters. The intuition just wasn't pushed far enough.