My exercise results
I found this exercise really challenging especially reversing the array in place. I had to research quite a lot and even when I found a way to implement it it took a major effort to get my head around it. I did realize of coarse that splitting the array was part of the solution but it was a real challenge.
Here is my homework
Exercise 4 (Range/Sum Functions)
The whole doc is required because the display features depend on elements in the body…
<!DOCTYPE html>
<html>
<head>
<title>Range and Sum Function</title>
</head>
<script language="JavaScript">
function writeToPage(data) {
// Write some data to page
if(!data) {
document.getElementById('myId').innerHTML = "";
} else {
document.getElementById('myId').innerHTML += data;
}
return;
}
function textColor(color) {
// adds a little color ot the output text
return "<font color=\"" + color + "\">" + this + "</font>";
}
String.prototype.color = textColor; // create new string property for color
function posToNegative(num) {
// converts step in range to negative if start > end
return -Math.abs(num);
}
function range(start, end, step) {
//alert(start + end + step)
// creates array while start is < end || start > end
var myArray = new Array();
if(start > end) {
// build the array
step = posToNegative(step); // if start > end make step negative
for(let i = start; i >= end; i += step) {
myArray.push(i);
}
} else {
for(let i = start; i <= end; i += step) {
myArray.push(i);
}
}
// Make the array text pretty to show to user
var display = "<h2>Function Range</h2>The numbers ";
for(let i = 0; i < myArray.length; i++) {
display += myArray[i].toString().color('green');
if(i < myArray.length -1) {
display += ", ";
}
}
writeToPage(display + " were written to " + "myArray".color('red'));
// write result of range() to the page.
return(myArray);
}
function sum(thisRange) {
writeToPage("<h2>Function Sum</h2>The numbers ");
var sum = 0;
for(let i = 0; i <= thisRange.length -1; i++) {
sum += thisRange[i];
writeToPage(Number(thisRange[i]).toString().color('green'))
if(i < thisRange.length -1) {
writeToPage(" + ");
} else {
writeToPage(" = ");
}
}
writeToPage(Number(sum).toString().color('green'));
return;
}
function getInputValues() {
// Gets input values from the user and retruns string
return prompt("I need 3 values to pass to the range().\n These should be a coma separated list of values\n for example\n 1, 10, 2 which convert to start, end, step respectivly");
}
function doIt() {
writeToPage("")
userRangeValues = getInputValues();
rangeValuesSplit = userRangeValues.split(",");
sum(range(Number(rangeValuesSplit[0]), Number(rangeValuesSplit[1]), Number(rangeValuesSplit[2])));
writeToPage("<br><br><button onClick='doIt()'>Try Another Calculation</button>")
writeToPage("</div>")
return;
}
</script>
<body id="body" onLoad="doIt()">
<div id="myId">
</div>
</body>
</html>
Exercise 4 (Reversing Arrays with Speed test)
The whole body is included because display depends on body element
Regarding the question of speed and which method is quicker??
Impossible to tell just by observation. All the research I have done researching this exercise leads me to believe there are too many variables at play to be truly certain. Calling properties of objects outside the local scope are suggested to be slower and less efficient. It is also suggested recursion is slower than looping.
For my exercise i used loops for both and the reverse function is using local declarations and objects and the inplace reverse is using global objects outside of the function scope. I couldn’t notice any observable difference in loops but when i attached the performance.now() object to both functions it turns out some of the suggestions from the internet on speed are incorrect and the function i expected to be faster which was using the local declared objects and declarations was much slower. In fact nearly 50% slower. I wonder if the same results are returned from a different computer.
<!DOCTYPE html>
<html>
<head>
<title>Reverse Array's with Speedtest</title>
<script language="JavaScript">
function writeToPage(data) {
document.getElementById('myID').innerHTML += data;
}
function reverse(array) {
let length = array.length - 1;
localArray = new Array();
for(let i = 0; i <= length; i++) {
localArray.push(array[length - i]);
}
writeToPage("<h2>Out of Place Reverse</h2>Initial array set to " + array + "<br>reversed localArray set to " + localArray);
return;
}
let inPlaceArray = [1,2,3,4,5,6,7,8,9,10];
let length = inPlaceArray.length;
let middle = length / 2;
let temp = null;
function reverseArrayInPlace() {
writeToPage("<h2>In Place Reverse</h2>Initial array set to " + inPlaceArray)
for(i = 0; i <= (length -1) / 2; i++) {
//alert(i)
temp = inPlaceArray[i];
inPlaceArray[i] = inPlaceArray[length - 1 - i];
inPlaceArray[length - 1 - i] = temp;
}
writeToPage("<br>reversed inPlaceArray = " + inPlaceArray);
}
function timeIt() {
var t0 = performance.now();
reverse([1,2,3,4,5,6,7,8,9,10]);
var t1 = performance.now();
writeToPage("<br>Duration of exeacution was " + (t1 - t0) + " ms");
t2 = performance.now();
reverseArrayInPlace();
t3 = performance.now();
writeToPage("<br>Duration of exeacution was " + (t3 - t2) + " ms");
if(t1 - t0 > t3 - t2) {
writeToPage("<h2>Results from the Speed Test</h2>")
writeToPage("<br>Reversing an array in place is " + ((t1 - t0) - (t3 - t2)) + " ms quicker.")
} else if(t3 - t2 > t1 - t0) {
writeToPage("<br>Reversing an array out of place is " + ((t3 - t2) - (t1 - t0)) + " ms quicker.")
} else {
writeToPage("There was no difference in speed detected.")
}
}
</script>
</head>
<body onLoad="timeIt()">
<center>
<div id="myID" style="width:50%; text-align:center;"></div>
</center>
</body>
</html>
One more additional extra to array reversing recursively
I got curious and decided to make one more addition to the script to account for recursion V’s looping in regard to speed and which is faster and the results were even more surprising to me. It was suggested in the eloquent javascript book that recursion was slower than looping. maybe I read it incorrectly but my final script shows that recursive reversing of in place array is the quickest.
<!DOCTYPE html>
<html>
<head>
<title>Reverse Array's with Speedtest Recursion V's Looping</title>
<script language="JavaScript">
function writeToPage(data) {
// Any text passed will be written to document
document.getElementById('myID').innerHTML += data;
}
function colorText(color) {
// Colors any call to it using the color passed to it.
return "<font color=\"" + color + "\">" + this + "</font>";
}
String.prototype.color = colorText; // Create an extra property using colorText()
function reverse(array) {
// Reverse the array out of place
// define some local variables
let length = array.length - 1;
localArray = new Array();
for(let i = 0; i <= length; i++) {
localArray.push(array[length - i]);
}
// When loop is complete write result
writeToPage("<h2>Out of Place Reverse</h2>Initial value of "
+ "array[]".color('green')
+ " set to "
+ array.toString().color('red')
+ "<br>The reversed value of "
+ "localArray[]".color('green') + " is "
+ localArray.toString().color('red'));
return;
}
// Set some globals for reverse in place
let inPlaceArray = [1,2,3,4,5,6,7,8,9,10];
let length = inPlaceArray.length;
let temp = null;
function reverseArrayInPlace() {
// Reverse the array in place
writeToPage("<h2>In Place Reverse</h2>Initial value of "
+ "inPlaceArray[]".color('green')
+ " set to "
+ inPlaceArray.toString().color('red'));
for(i = 0; i <= (length -1) / 2; i++) {
temp = inPlaceArray[i];
inPlaceArray[i] = inPlaceArray[length - 1 - i];
inPlaceArray[length - 1 - i] = temp;
}
// When loop is complete write the result
writeToPage("<br>The reversed value of "
+ "inPlaceArray[]".color('green')
+ "is "
+ inPlaceArray.toString().color('red'));
}
// Set some globals for the recursive function
let inPlaceArray1 = [1,2,3,4,5,6,7,8,9,10];
let length1 = inPlaceArray1.length;
function reverseArrayInPlace1(cnt) {
// Recursive function to reverse array in place
if(cnt <= (length1 - 1) / 2) {
temp = inPlaceArray1[cnt]; // Reuse previous temp variable
inPlaceArray1[cnt] = inPlaceArray1[length1 - 1 - cnt];
inPlaceArray1[length1 - 1 - cnt] = temp;
return reverseArrayInPlace1(++cnt);
} else {
// When recursion complete write the result
writeToPage("<br>The reversed value of "
+ "inPlaceArray1".color('green')
+ "is "
+ inPlaceArray1.toString().color('red'));
return;
}
}
function timeIt() {
// To test which method is faster will use performance.now() to time
// duration of of function..
writeToPage("<h1>Reverse Array Looping/Recursive</h1>")
var t0 = performance.now(); // Set start of timer for reverse()
reverse([1,2,3,4,5,6,7,8,9,10]);
var t1 = performance.now(); // End timer for reverse()
writeToPage("<br>Duration of exeacution was "
+ (t1 - t0).toString().color('red')
+ " ms");
t2 = performance.now(); // Start timer for reverseArrayInPlace()
reverseArrayInPlace();
t3 = performance.now(); // End timer for reverseArrayInPlace()
writeToPage("<br>Duration of exeacution was "
+ (t3 - t2).toString().color('red')
+ " ms");
writeToPage("<h2>Reverse Array in Place with recursion</h2>");
writeToPage("Initial value of "
+ "inPlaceArray1[]".color('green')
+ "is "
+ inPlaceArray1.toString().color('red'));
t4 = performance.now(); // Start timer for recursive reverseArrayInPlace1()
reverseArrayInPlace1(0);
t5 = performance.now(); // End timer for recursive reverseArrayInPlace1()
writeToPage("<br>Duration of execution was "
+ (t5 - t4).toString().color('red')
+ " ms.");
writeToPage("<h2>Results from the Speed Test</h2>");
if(t1 - t0 > t3 - t2 && t5 - t4 > t3 - t2) {
// All timers set now do some condition testing
// Then perform the math to figure out which is faster
// Then compare fastest to the 2 slowest reverses.
writeToPage("<br>Reversing an array in place is <br>"
+ ((t1 - t0) - (t3 - t2)).toString().color('red')
+ " ms quicker than out of place and <br>"
+ ((t5 - t4)- (t3 - t2)).toString().color('red')
+ " ms quicker than recursion.");
} else if(t3 - t2 > t1 - t0 && t5 - t4 > t1 - t0) {
writeToPage("<br>Reversing an array out of place is <br>"
+ ((t3 - t2) - (t1 - t0)).toString().color('red')
+ " ms quicker than in place and <br>"
+ ((t5 - t4) - (t1 - t0)).toString().color('red')
+ " ms quicker than recursion.");
} else if(t1 - t0 > t5 -t4 && t3 - t2 > t5 - t4 ){
writeToPage("Reversing an array in place with Recursion is <br>"
+ ((t1 - t0) - (t5 - t4)).toString().color('red')
+ " ms quicker than out of place for loop and <br>"
+ ((t3 - t2) -(t5 - t4)).toString().color('red')
+ " ms quicker than in place for loop.");
} else {
writeToPage("<h2>Shocking Result</h2>Back to drawing board.");
}
}
</script>
</head>
<body onLoad="timeIt()">
<center>
<div id="myID" style="width:50%; text-align:center;"></div>
</center>
</body>
</html>
P.S perhaps i jumped the gun too soon. earlier the recursive function was registering fastest 100% of the time and now while i have been doing some cosmetic surgery to my code it appears the out of place loop is coming in quickest now. Im not sure what is going on any more. Is it possible to have so much variability in the speeds of execution. Is it a side effect of performance.now(), anyway i tried to be 100% conclusive on speed and it seems not possible at the moment.