date-performance 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+