Commit d5b16674 authored by Oskar Kalbag's avatar Oskar Kalbag

Added a timer and some profiling code.

parent 3cf55b77
......@@ -3,6 +3,11 @@ tally = require './lib/tally-express.coffee'
superagent = require 'superagent'
timer = require './lib/timer.coffee'
# Time the app startup
timer.reset()
#
# Set up Express with Tally as the templating engine.
#
......@@ -45,20 +50,32 @@ app.get '/hybrid', (request, response) ->
#
app.get '/posts', (request, response) ->
# Time the data call
timer.reset()
superagent.get('https://alpha-api.app.net/stream/0/posts/stream/global')
.end (globalTimelineResponse) ->
timer.elapsedTime('Data transfer from App.net')
if globalTimelineResponse.body
# Attach a custom function to the data to count the number of posts
globalTimelineResponse.body.numberOfPosts = ->
return this.data.length
# Time the template render
timer.reset()
response.render 'posts.html', globalTimelineResponse.body
timer.elapsedTime('Template render')
else
response.render 'posts.html', {error: 'Bad response from Twitter'}
app.listen 3000
console.log 'The Tally sample is listening on port 3000…'
timer.elapsedTime('Server start')
// Generated by CoffeeScript 1.4.0
(function() {
var app, data, express, superagent, tally;
var app, data, express, superagent, tally, timer;
express = require('express');
......@@ -8,6 +8,10 @@
superagent = require('superagent');
timer = require('./lib/timer.coffee');
timer.reset();
app = express();
app.engine('html', tally.__express);
......@@ -48,12 +52,16 @@
});
app.get('/posts', function(request, response) {
timer.reset();
return superagent.get('https://alpha-api.app.net/stream/0/posts/stream/global').end(function(globalTimelineResponse) {
timer.elapsedTime('Data transfer from App.net');
if (globalTimelineResponse.body) {
globalTimelineResponse.body.numberOfPosts = function() {
return this.data.length;
};
return response.render('posts.html', globalTimelineResponse.body);
timer.reset();
response.render('posts.html', globalTimelineResponse.body);
return timer.elapsedTime('Template render');
} else {
return response.render('posts.html', {
error: 'Bad response from Twitter'
......@@ -66,4 +74,6 @@
console.log('The Tally sample is listening on port 3000…');
timer.elapsedTime('Server start');
}).call(this);
#
# Timer (modified from http://stackoverflow.com/questions/10617070/how-to-measure-execution-time-of-javascript-code-with-callbacks)
#
timers = {}
start = process.hrtime()
reset = ->
start = process.hrtime()
elapsedTime = (note) ->
precision = 3 # 3 decimal places
elapsed = process.hrtime(start)[1] / 1000000; # ms from nanoseconds
if not (timers[note] and Array.isArray timers[note])
timers[note] = []
times = timers[note]
times.push elapsed
sum = times.reduce (previousValue, currentValue) ->
return previousValue + currentValue;
sum = sum.toFixed(precision)
numTries = times.length
average = (sum / numTries).toFixed(precision)
min = (Math.min.apply(Math, times)).toFixed(precision)
max = (Math.max.apply(Math, times)).toFixed(precision)
console.log("\n#{note}:\n
Elapsed: #{elapsed} ms.\n
Average: #{average} ms over #{numTries} tries (min: #{min} ms, max: #{max} ms).")
start = process.hrtime() # reset the timer
exports.reset = reset
exports.elapsedTime = elapsedTime
// Generated by CoffeeScript 1.4.0
(function(){var e,t,n,r;r={};n=process.hrtime();t=function(){return n=process.hrtime()};e=function(e){var t,i,s,o,u,a,f,l;a=3;i=process.hrtime(n)[1]/1e6;if(!r[e]||!Array.isArray(r[e]))r[e]=[];l=r[e];l.push(i);f=l.reduce(function(e,t){return e+t});f=f.toFixed(a);u=l.length;t=(f/u).toFixed(a);o=Math.min.apply(Math,l).toFixed(a);s=Math.max.apply(Math,l).toFixed(a);console.log("\n"+e+":\n Elapsed: "+i+" ms.\n Average: "+t+" ms over "+u+" tries (min: "+o+" ms, max: "+s+" ms).");return n=process.hrtime()};exports.reset=t;exports.elapsedTime=e}).call(this);
\ No newline at end of file
......@@ -2,7 +2,7 @@
<html lang='en'>
<head>
<meta charset='utf-8'>
<title></title>
<title>App.net Global Timeline</title>
<meta name='viewport' content='width=device-width'>
<link rel='stylesheet' type='text/css' href='posts.css'>
......@@ -14,17 +14,17 @@
<p>The latest <span data-tally-text='numberOfPosts'>NN</span> posts from <a href='http://join.app.net'>App.net</a>.</p>
<ul>
<li data-tally-repeat='post data'>
<img data-tally-attr='src post.user.avatar_image.url' src='http://placehold.it/100x100' alt='User name’s avatar'>
<img data-tally-attr='src post.user.avatar_image.url; alt post.user.name' src='http://placehold.it/100x100' alt=''>
<p><a class='user' data-tally-attr='href post.user.canonical_url' data-tally-text='post.user.name' href=''>Jane Person</a>
<p><a class='user' data-tally-attr='href post.user.canonical_url' data-tally-text='post.user.name' href=''>Jane User</a>
<span class='postText' data-tally-text='post.text'>This is a sample post. This list item will be the one that is used as the prototype for the final list. Working with actual content as a place‐holder means you can do things like add (and style) <a href='http://aralbalkan.com'>links</a>, like this one to Aral’s <a href='http://moderniosdevelopment.com'>Modern iOS Development Workshop</a> in April, 2013 in the UK.</span></p>
</li>
<li data-tally-if='false'><img src='http://placehold.it/100x100' alt='User name’s avatar'><p><a class='user' href=''>John Person</a> <span class='postText'>This is another sample post. These will only display when viewing the unprocessed template to help you tweak the design of the page.</span></li>
<li data-tally-if='false'><img src='http://placehold.it/100x100' alt='User name’s avatar'><p><a class='user' href=''>John User</a> <span class='postText'>This is another sample post. These will only display when viewing the unprocessed template to help you tweak the design of the page.</span></li>
<li data-tally-if='false'><img src='http://placehold.it/100x100' alt='User name’s avatar'><p><a class='user' href=''>John Person</a> <span class='postText'>By the way, did we mention that you can learn how to make native iPhone and iPad apps using Objective-C and Cocoa Touch in just three days of hands‐on coding with Aral at his <a href='http://moderniosdevelopment.com'>Modern iOS Development Workshop</a> in Brighton this April?</p><p>Oh, we did, ah… well, at least that’s filled up this longer post sample that has multiple paragraphs so that we can design for that eventuality.</span></li>
<li data-tally-if='false'><img src='http://placehold.it/100x100' alt='User name’s avatar'><p><a class='user' href=''>Osky Kalbag</a> <span class='postText'>By the way, did we mention that you can learn how to make native iPhone and iPad apps using Objective-C and Cocoa Touch in just three days of hands‐on coding with Aral at his <a href='http://moderniosdevelopment.com'>Modern iOS Development Workshop</a> in Brighton this April?</p><p>Oh, we did, ah… well, at least that’s filled up this longer post sample that has multiple paragraphs so that we can design for that eventuality.</span></li>
<li data-tally-if='false'><img src='http://placehold.it/100x100' alt='User name’s avatar'><p><a class='user' href=''>Yet A. Nother-Person</a> <span class='postText'>By using a range of copy&#8202;&#8202;and actual content&#8202;&#8202; you can get a better feel for the constraints of your design e.g., what happens with really long URLs like this: http://thisisareallylongurlohmyyourerightitisaverylongurlwhatlongurlsyouhavegrandma.com</p></li>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment