date-performance 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/AUTHORS +1 -0
  2. data/BENCHMARKS +30 -0
  3. data/COPYING +22 -0
  4. data/README.txt +134 -0
  5. data/Rakefile +90 -0
  6. data/doc/asciidoc.conf +21 -0
  7. data/doc/changes.html +32 -0
  8. data/doc/changes.txt +7 -0
  9. data/doc/images/icons/callouts/1.png +0 -0
  10. data/doc/images/icons/callouts/10.png +0 -0
  11. data/doc/images/icons/callouts/11.png +0 -0
  12. data/doc/images/icons/callouts/12.png +0 -0
  13. data/doc/images/icons/callouts/13.png +0 -0
  14. data/doc/images/icons/callouts/14.png +0 -0
  15. data/doc/images/icons/callouts/15.png +0 -0
  16. data/doc/images/icons/callouts/2.png +0 -0
  17. data/doc/images/icons/callouts/3.png +0 -0
  18. data/doc/images/icons/callouts/4.png +0 -0
  19. data/doc/images/icons/callouts/5.png +0 -0
  20. data/doc/images/icons/callouts/6.png +0 -0
  21. data/doc/images/icons/callouts/7.png +0 -0
  22. data/doc/images/icons/callouts/8.png +0 -0
  23. data/doc/images/icons/callouts/9.png +0 -0
  24. data/doc/images/icons/caution.png +0 -0
  25. data/doc/images/icons/example.png +0 -0
  26. data/doc/images/icons/home.png +0 -0
  27. data/doc/images/icons/important.png +0 -0
  28. data/doc/images/icons/next.png +0 -0
  29. data/doc/images/icons/note.png +0 -0
  30. data/doc/images/icons/prev.png +0 -0
  31. data/doc/images/icons/tip.png +0 -0
  32. data/doc/images/icons/up.png +0 -0
  33. data/doc/images/icons/warning.png +0 -0
  34. data/doc/license.html +42 -0
  35. data/doc/license.txt +1 -0
  36. data/doc/stylesheets/handbookish-manpage.css +36 -0
  37. data/doc/stylesheets/handbookish-quirks.css +2 -0
  38. data/doc/stylesheets/handbookish.css +119 -0
  39. data/ext/date_performance.c +401 -0
  40. data/ext/extconf.rb +9 -0
  41. data/lib/date/memoize.rb +86 -0
  42. data/lib/date/performance.rb +44 -0
  43. data/misc/asciidoc.rake +121 -0
  44. data/misc/project.rake +922 -0
  45. data/test/date_memoize_test.rb +70 -0
  46. data/test/extension_test.rb +120 -0
  47. metadata +110 -0
data/AUTHORS ADDED
@@ -0,0 +1 @@
1
+ rtomayko = Ryan Tomayko <rtomayko@gmail.com>
@@ -0,0 +1,30 @@
1
+ == WITH EXTENSION ==============================
2
+ comparison
3
+ 0.030000 0.000000 0.030000 ( 0.027561)
4
+ greater_than
5
+ 0.030000 0.000000 0.030000 ( 0.026667)
6
+ new_civil
7
+ 0.060000 0.000000 0.060000 ( 0.063149)
8
+ new_jd
9
+ 0.060000 0.000000 0.060000 ( 0.058935)
10
+ strftime
11
+ 0.020000 0.000000 0.020000 ( 0.018389)
12
+ strftime_after_new
13
+ 0.080000 0.000000 0.080000 ( 0.082086)
14
+ strptime
15
+ 0.070000 0.000000 0.070000 ( 0.068235)
16
+ == WITHOUT EXTENSION ===========================
17
+ comparison
18
+ 0.030000 0.000000 0.030000 ( 0.027135)
19
+ greater_than
20
+ 0.030000 0.000000 0.030000 ( 0.026128)
21
+ new_civil
22
+ 0.300000 0.000000 0.300000 ( 0.303737)
23
+ new_jd
24
+ 0.110000 0.000000 0.110000 ( 0.110033)
25
+ strftime
26
+ 0.230000 0.000000 0.230000 ( 0.231178)
27
+ strftime_after_new
28
+ 0.850000 0.000000 0.850000 ( 0.843894)
29
+ strptime
30
+ 3.000000 0.030000 3.030000 ( 3.033587)
data/COPYING ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License
2
+ ===============
3
+
4
+ Date::Performance is Copyright (c) 2007-08, Ryan Tomayko
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,134 @@
1
+ Date::Performance
2
+ =================
3
+
4
+ This package adds some semblance of performance to Ruby's core Date class
5
+ using a combination of different techniques:
6
+
7
+ 1. Implements various core *Date* methods in C. This is nowhere near a
8
+ complete rewrite of all *Date* features but many of the hot spots have
9
+ been replaced with machine code.
10
+
11
+ 2. Provide alternate implementations of `strftime` and `strptime` in C. The stock
12
+ date formatting and parsing methods are extremely slow compared to their
13
+ libc counterparts. *Date#sys_strftime* and *Date::sys_strptime* are light
14
+ facades on top of the system's `strftime(2)` and `strptime(2)`. The system
15
+ methods run 10x and 50x (yes, _fifty-ecks_) faster than their Ruby based counterparts,
16
+ respectively. Unfortunately, `strftime(2)` and `strptime(2)` implementations vary from
17
+ system to system and have various limitations not found in the core Date
18
+ implementation so can not safely be used as replacements for the core methods.
19
+
20
+ 3. Memoization. The *Date::Memoize* module can be used to speed certain
21
+ types of repetitive date processing significantly. This file must be
22
+ required separately.
23
+
24
+ Synopsis
25
+ --------
26
+
27
+ This package is mostly transparent after an initial require:
28
+
29
+ require 'date/performance'
30
+ Date.new 1912, 6, 23
31
+ # Wow! That was fast!
32
+
33
+ *Date::Performance* is not used directly but automatically replaces core *Date*
34
+ methods when required.
35
+
36
+ In addition to the C extension, the *Date::Memoization* module can be used to
37
+ speed things up even further in some cases by making a trade off between space
38
+ and time:
39
+
40
+ require 'date/memoize'
41
+ Date.new 1912, 6, 23
42
+ Date.parse '1912-06-23'
43
+
44
+ Requiring the file automatically replaces *Date::new* / *Date::civil*, *Date::parse*,
45
+ and *Date::jd* methods with memoized versions.
46
+
47
+ Installation / Hacking
48
+ ----------------------
49
+
50
+ This package has been tested on the following platforms:
51
+
52
+ * FreeBSD 5.4 (x86) and 6.1 (AMD64)
53
+ * Linux / Fedora Core 6 (x86)
54
+ * MacOS X (Intel)
55
+
56
+ The easiest way to install the package is to use RubyGems:
57
+
58
+ $ gem install date-performance --source=http://tomayko.com
59
+
60
+ Old versions and other dist formats are available at:
61
+
62
+ http://tomayko.com/dist/date-performance/
63
+
64
+ A git repository is also available:
65
+
66
+ $ git clone git://github.com/rtomayko/date-performance.git
67
+
68
+ Background
69
+ ----------
70
+
71
+ The *Date* class is often the cause of poor performance in Ruby programs. A frequent
72
+ suggestion is to use the *Time* class, which is much faster, but that solution has
73
+ correctness problems in a wide range of data typing cases. It is often the case that
74
+ you want separate *Date*, *Time*, and *DateTime* types.
75
+
76
+ There are a couple of reasons why *Date* runs slowly when compared with
77
+ *Time*. The common assumption is that this is mostly due to *Time* being
78
+ written in C and *Date* being written in Ruby. While that clearly has an
79
+ impact, I would argue that the reason *Date* is slow is because it's not
80
+ designed to be fast. The code opts for readability over performance in almost
81
+ every case. _This is a feature_.
82
+
83
+ Have you read the *date.rb* documentation [1]? The implementation is pretty
84
+ hard core; it can handle a lot of weird cases that *Time* [2] does not and
85
+ would appear to be a correct implementation of date handling, which has the
86
+ usual side-effect of being slow.
87
+
88
+ The *Date* implementation uses a single Astronomical Julian Day (AJD) number
89
+ to represent dates internally. In fact, *Date#initialize* takes a
90
+ single `ajd` argument, which means that all date forms that are commonly used
91
+ (UNIX timestamp, Civil, etc.) must be converted to an AJD before we can even
92
+ instantiate the thing.
93
+
94
+ The real performance hit seems to come from the various rational number
95
+ operations performed on the way from a civil, ordinal, and julian date to
96
+ an AJD.
97
+
98
+ When I began writing *Date::Performance*, I was getting pretty big (3x - 4x)
99
+ performance boosts in many places simply by optimizing the Ruby code a bit.
100
+ These boosts came at the expense of readability, however, and so the decision
101
+ was made to go for _maximum unreadability_ and implement the boosts in C.
102
+
103
+ There's a nice balance here: the Ruby implementation reads like a spec,
104
+ while the C version implements it for quickness.
105
+
106
+ Memoization
107
+ -----------
108
+
109
+ In addition to the C extension, this package includes a separate *Date::Memoize*
110
+ module that can further speed up date processing in situations where the range
111
+ of dates being manipulated is fairly dense and the same dates are being
112
+ created repeatedly. Working with databases and flat files are two examples
113
+ where memoization may help significantly.
114
+
115
+ The *Date::Memoize* module replaces various Date constructor methods (`new`,
116
+ `civil`, and `parse`) with memoized[http://en.wikipedia.org/wiki/Memoization]
117
+ versions (see *Date::Memoization* for details). The best way to determine
118
+ whether memoization is right for you is to add it to your project and see
119
+ what happens.
120
+
121
+ License
122
+ -------
123
+
124
+ MIT. See the COPYING file included in the distribution for more
125
+ information.
126
+
127
+ See Also
128
+ --------
129
+
130
+ * [1] Ruby *Date* Implementation Notes and Documentation:
131
+ http://www.ruby-doc.org/docs/rdoc/1.9/files/_/lib/date_rb.html
132
+
133
+ * [2] Ruby *Time* documentation
134
+ http://www.ruby-doc.org/docs/rdoc/1.9/classes/Time.html
@@ -0,0 +1,90 @@
1
+ load 'misc/asciidoc.rake'
2
+ load 'misc/project.rake'
3
+
4
+ Project.new "Date::Performance" do |p|
5
+ p.package_name = 'date-performance'
6
+ p.version_file = 'lib/date/performance.rb'
7
+ p.summary = "Adds some semblance of performance to Ruby's core Date class."
8
+ p.project_url = "http://tomayko.com/src/date-performance/"
9
+ p.extra_files.include "ext/**/*.{rb,c,h}", "AUTHORS", "BENCHMARKS"
10
+ p.configure_package {|spec| spec.extensions = FileList["ext/**/extconf.rb"].to_a }
11
+ p.author = 'Ryan Tomayko <r@tomayko.com>'
12
+ p.rubyforge_project = 'wink'
13
+
14
+ p.remote_dist_location = "tomayko.com:/dist/#{p.package_name}"
15
+ p.remote_branch_location = "tomayko.com:/src/#{p.package_name}.git"
16
+ p.remote_doc_location = "tomayko.com:/src/#{p.package_name}"
17
+ end
18
+
19
+ task :default => [ :compile, :test ]
20
+
21
+ file 'doc/index.txt' => 'README.txt' do |f|
22
+ cp 'README.txt', f.name
23
+ end
24
+
25
+ CLEAN.include [ "ext/*.{o,bundle}", "lib/*.{bundle,so,dll}" ]
26
+ CLOBBER.include [ "ext/Makefile" ]
27
+
28
+ if File.exist? 'misc/date-1.8.5'
29
+ desc "Run unit tests with Date from Ruby 1.8.5"
30
+ Rake::TestTask.new 'test:ruby185' do |t|
31
+ t.libs << "test"
32
+ t.libs << "misc/date-1.8.5"
33
+ t.test_files = FileList['test/*_test.rb']
34
+ t.verbose = true
35
+ end
36
+ end
37
+
38
+ task 'benchmark.without' do |t|
39
+ verbose false do
40
+ puts '== WITHOUT EXTENSION ==========================='
41
+ ruby "-Ilib test/benchmarks.rb"
42
+ end
43
+ end
44
+
45
+ task 'benchmark.with' do |t|
46
+ verbose false do
47
+ puts '== WITH EXTENSION =============================='
48
+ ruby "-Ilib -rdate/performance test/benchmarks.rb"
49
+ end
50
+ end
51
+
52
+ desc "Run benchmarks"
53
+ task :benchmark => [ 'benchmark.without', 'benchmark.with' ]
54
+
55
+ # Extension =================================================================
56
+
57
+ DLEXT = Config::CONFIG['DLEXT']
58
+
59
+ directory "lib"
60
+
61
+ desc "Build the extension"
62
+ task "date_performance" => [ "lib/date_performance.#{DLEXT}" ]
63
+
64
+ file "ext/Makefile" => FileList[ "ext/*.{c,h,rb}" ] do
65
+ Dir.chdir("ext") { ruby "extconf.rb" }
66
+ end
67
+
68
+ file "ext/date_performance.#{DLEXT}" => FileList["ext/*.c", "ext/Makefile"] do |f|
69
+ Dir.chdir("ext") { sh "make" }
70
+ end
71
+
72
+ file "lib/date_performance.#{DLEXT}" => [ "ext/date_performance.#{DLEXT}" ] do |t|
73
+ cp "ext/date_performance.#{DLEXT}", t.name
74
+ end
75
+
76
+ desc "Compiles all extensions"
77
+ task :compile => [ "lib/date_performance.#{DLEXT}" ]
78
+
79
+ # Rubyforge =================================================================
80
+
81
+ VERS = Project.current.version
82
+ PKGNAME = "dist/date-performance-#{VERS}"
83
+
84
+ desc 'Publish new release to rubyforge'
85
+ task :release => [ "#{PKGNAME}.gem", "#{PKGNAME}.tar.gz" ] do |t|
86
+ sh <<-end
87
+ rubyforge add_release wink date-performance #{VERS} #{PKGNAME}.gem &&
88
+ rubyforge add_file wink date-performance #{VERS} #{PKGNAME}.tar.gz
89
+ end
90
+ end
@@ -0,0 +1,21 @@
1
+ [attributes]
2
+ outfilesuffix=.html
3
+ gt=>
4
+ pagewidth=800
5
+ encoding=UTF-8
6
+ textwidth=70
7
+ newline=\n
8
+ backslash=\
9
+ nbsp=&#160;
10
+ amp=&
11
+ basebackend=html
12
+ quirks
13
+ brvbar=|
14
+ tabsize=4
15
+ pageunits=
16
+ empty=
17
+ stylesdir=stylesheets
18
+ theme=handbookish
19
+ linkcss=yes
20
+ icons=yes
21
+ iconsdir=./images/icons
@@ -0,0 +1,32 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
6
+ <meta name="generator" content="AsciiDoc 8.2.5" />
7
+ <link rel="stylesheet" href="stylesheets/handbookish.css" type="text/css" />
8
+ <title>Date::Performance ChangeLog</title>
9
+ </head>
10
+ <body>
11
+ <div id="header">
12
+ <h1>Date::Performance ChangeLog</h1>
13
+ <span id="author">Ryan Tomayko</span><br />
14
+ <span id="email"><tt>&lt;<a href="mailto:r@tomayko.com">r@tomayko.com</a>&gt;</tt></span><br />
15
+ </div>
16
+ <div id="preamble">
17
+ <div class="sectionbody">
18
+ <div class="listingblock">
19
+ <div class="content"><!-- Generator: GNU source-highlight 2.9
20
+ by Lorenzo Bettini
21
+ http://www.lorenzobettini.it
22
+ http://www.gnu.org/software/src-highlite -->
23
+ <pre><tt></tt></pre></div></div>
24
+ </div>
25
+ </div>
26
+ <div id="footer">
27
+ <div id="footer-text">
28
+ Last updated 2008-07-12 08:15:20 PDT
29
+ </div>
30
+ </div>
31
+ </body>
32
+ </html>
@@ -0,0 +1,7 @@
1
+ :author:!
2
+ = {project-name} ChangeLog
3
+
4
+ [changelog]
5
+ source~~~~~~~~~~~~~~~~~
6
+ include::../ChangeLog[]
7
+ source~~~~~~~~~~~~~~~~~
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,42 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
2
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
6
+ <meta name="generator" content="AsciiDoc 8.2.5" />
7
+ <link rel="stylesheet" href="stylesheets/handbookish.css" type="text/css" />
8
+ <title>The MIT License</title>
9
+ </head>
10
+ <body>
11
+ <div id="header">
12
+ <h1>The MIT License</h1>
13
+ <span id="author">Ryan Tomayko</span><br />
14
+ <span id="email"><tt>&lt;<a href="mailto:r@tomayko.com">r@tomayko.com</a>&gt;</tt></span><br />
15
+ </div>
16
+ <div id="preamble">
17
+ <div class="sectionbody">
18
+ <div class="para"><p>Date::Performance is Copyright (c) 2007-08, Ryan Tomayko</p></div>
19
+ <div class="para"><p>Permission is hereby granted, free of charge, to any person obtaining a copy
20
+ of this software and associated documentation files (the "Software"), to deal
21
+ in the Software without restriction, including without limitation the rights
22
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23
+ copies of the Software, and to permit persons to whom the Software is
24
+ furnished to do so, subject to the following conditions:</p></div>
25
+ <div class="para"><p>The above copyright notice and this permission notice shall be included in all
26
+ copies or substantial portions of the Software.</p></div>
27
+ <div class="para"><p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33
+ SOFTWARE.</p></div>
34
+ </div>
35
+ </div>
36
+ <div id="footer">
37
+ <div id="footer-text">
38
+ Last updated 2008-07-12 08:15:21 PDT
39
+ </div>
40
+ </div>
41
+ </body>
42
+ </html>
@@ -0,0 +1 @@
1
+ include::../COPYING[]
@@ -0,0 +1,36 @@
1
+ /* Overrides for manpage documents */
2
+ body {
3
+ font-family: 'Lucida Console', 'Bitstream Vera Sans Mono', 'Courier New', monospace;
4
+ color:#555;
5
+ }
6
+ tt {
7
+ font-family:'Lucida Console', 'Bitstream Vera Sans Mono', 'Courier New', monospace;
8
+ font-weight:bold;
9
+ font-size:100%; /* overrides base stylesheet */
10
+ }
11
+ em {
12
+ font-style:normal;
13
+ color:#222;
14
+ }
15
+ dt { font-weight:bold; color:#000 }
16
+
17
+ h1 {
18
+ font-size:1.714em; /* 24px */
19
+ line-height:1.666; /* 40px */
20
+ margin:1.666em 0; /* 40px */
21
+ padding: 0.3333em 0; /* 8px */
22
+ border-bottom:0.08333em solid #fff; /* 2px */
23
+ border-top:0.08333em solid #fff; /* 2px */
24
+ text-align:center;
25
+ }
26
+ h2 {
27
+ font-size:1.142em; /* 16px */
28
+ line-height:1.25; /* 20px baseline */
29
+ margin:1.25em 0; /* 20px */
30
+ border-bottom:0;
31
+ border-top:0;
32
+ }
33
+ div.sectionbody {
34
+ margin-left: 5%;
35
+ }
36
+