2

I want to create a copyright (c) 2014 notice in my footer.

But I want it to cycle through all the years/months/days without me having to change that.

I have a _footer.html.erb partial where I am doing this.

The obvious easy answer is just to say <%= Time.now.year %>.

That means that every time the view is loaded, it has to do a Ruby call at the end. It seems kinda expensive, considering that this will appear on every single page of the site and it will have to make a Ruby call for every single load.

Is there a more lightweight/streamlined way, where maybe the value can be cached and be displayed from the cache?

marcamillion
  • 32,933
  • 55
  • 189
  • 380

5 Answers5

8

You shoudn't trust your intuition when it comes to performances, it is wiser to measure.

The following example compares the time taken to compute Time.now.year with the time taken to extract the value from Redis or Memcached:

require 'redis'
R = Redis.new
R.set('year', Time.now.year)

require 'memcached'
M = Memcached.new
M.set('year', Time.now.year)

require 'fruity'
compare(
  compute:  -> { Time.now.year },
  redis:    -> { R.get('year').to_i },
  memcache: -> { M.get('year') }
)

Output:

Running each test 256 times. Test will take about 2 seconds.
compute is faster than memcache by 11x ± 1.0
memcache is faster than redis by 3x ± 0.1

That said, just call Time.now.year, it wouldn't worth find an alternative.

toro2k
  • 19,020
  • 7
  • 64
  • 71
  • 1
    TIL about fruity. Looks very useful. Link for others: https://github.com/marcandre/fruity – Yule May 08 '14 at 09:26
3
<%= cache 'time_of_year', expires_in: 1.day do %>
    <%= Time.now.year %>
<%= end %>

Read more here. http://guides.rubyonrails.org/caching_with_rails.html

IMO, I don't think this will make it any faster though, could even be slower.

Eyeslandic
  • 14,553
  • 13
  • 41
  • 54
  • Thanks for this. I am just going to go with vanilla `Time.now.year` for now...but if I ever need fragment caching like this I will come back to this answer. Thanks much! – marcamillion May 07 '14 at 17:50
  • @marcamillion Consider marking it as an answer though. – Eyeslandic May 07 '14 at 18:34
3

I am pretty sure it is faster to recalculate Time.now.year at every request.

Fetching that value from a cache will result in loading a file from a disk or a connection to a service like memcached via socket. That sound to me way more expensive than doing this simple Time.now.year calculation.

spickermann
  • 100,941
  • 9
  • 101
  • 131
2

I wouldn't worry to much for that but if you must optimize it you could have something like that in your ApplicationHelper:

def current_year
  @year ||= Time.now.year
end

and use current_year in your views.

You could also use a simple caching to avoid the call altogether.

Personally I find both approaches an overkill which take away from readability/maintainability for no good reason :)

Kostas Rousis
  • 5,918
  • 1
  • 33
  • 38
1

You could use Javascript, like so:

 var currentyear = new Date().getFullYear();
 $(".element").html(currentyear);

Or a better way will be to use what @iceman suggested (caching)

Community
  • 1
  • 1
Richard Peck
  • 76,116
  • 9
  • 93
  • 147