faster_path 0.2.6 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64eada185c9f0597ca475f6f94f77299b5ebf0458fe6de87d5a041d7a6d69dfe
4
- data.tar.gz: 5d14a11a8a468eba873da3b6e4d2628e8fdbb5d88150c60575b6266a4df5f726
3
+ metadata.gz: 84e796cda8b8704b7a6f5e2a2e69acc012f611b66f89642f34149f88c645ae34
4
+ data.tar.gz: 8b20ae9b2bcaebaf44dbc56500ad539e5082169d729a24685c0c9a446ee4dd6b
5
5
  SHA512:
6
- metadata.gz: 2c2121f4aa08b8979818480b78980f07563483befa52c2493821f7a562d0f213a762f192ed1b7ec3c67050c9f0a72bccbb65a0dcb1d7258316ffbe0ae7480c2f
7
- data.tar.gz: 0c16b9cd5e5ff583717d664228bfac6ac4b6b5e46c7a92c8a3170ae050ae9ec6974dc597a1c9aff8232e77515b3d5cd70bfccd33c5fa67402091af660dd7f502
6
+ metadata.gz: '091d419f3c849b46f493a3ae47fcf59d064c83ffec898856032ffa47d84e68ace558e882437f95a662bd84b77cdbe0182f7b62c5cd1316fd250a54d49afe3046'
7
+ data.tar.gz: ecbdcad442c08c9eee827f30672f585f34450e0b4a72905936fe49a7eb251a7e8c461a0a5fcaa10d19a1e36ef304ada0b8b8f1bff1d0cab31017bad35ddd3743
data/Cargo.toml CHANGED
@@ -8,6 +8,9 @@ repository = "https://github.com/danielpclark/faster_path"
8
8
  license = "MIT OR Apache-2.0"
9
9
  readme = "README.md"
10
10
 
11
+ [package.metadata.thermite]
12
+ github_releases = true
13
+
11
14
  [lib]
12
15
  name = "faster_path"
13
16
  crate-type = ["dylib"]
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![TravisCI Build Status](https://travis-ci.org/danielpclark/faster_path.svg?branch=master)](https://travis-ci.org/danielpclark/faster_path)
4
4
  [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/10ul0gk3cwhlt2lj/branch/master?svg=true)](https://ci.appveyor.com/project/danielpclark/faster-path/branch/master)
5
5
  [![Latest Tag](https://img.shields.io/github/tag/danielpclark/faster_path.svg)](https://github.com/danielpclark/faster_path/tags)
6
- [![Commits Since Last Release](https://img.shields.io/github/commits-since/danielpclark/faster_path/v0.2.6.svg)](https://github.com/danielpclark/faster_path/pulse)
6
+ [![Commits Since Last Release](https://img.shields.io/github/commits-since/danielpclark/faster_path/v0.3.1.svg)](https://github.com/danielpclark/faster_path/pulse)
7
7
  [![Binary Release](https://img.shields.io/github/release/danielpclark/faster_path.svg)](https://github.com/danielpclark/faster_path/releases)
8
8
  [![Coverage Status](https://coveralls.io/repos/github/danielpclark/faster_path/badge.svg)](https://coveralls.io/github/danielpclark/faster_path)
9
9
  [![Inline docs](http://inch-ci.org/github/danielpclark/faster_path.svg?branch=master)](http://inch-ci.org/github/danielpclark/faster_path)
@@ -55,7 +55,7 @@ Running `stackprof tmp/2016-06-09T00:42:10-04:00-stackprof-cpu-myapp.dump`. Exec
55
55
  108 (1.5%) 14 (0.2%) ActionView::Helpers::AssetUrlHelper#asset_path
56
56
  ```
57
57
 
58
- Here are some addtional stats. From Rails loading to my home page, these methods are called _(not directly, Rails & gems call them)_ this many times. And the home page has minimal content.
58
+ Here are some additional stats. From Rails loading to my home page, these methods are called _(not directly, Rails & gems call them)_ this many times. And the home page has minimal content.
59
59
  ```ruby
60
60
  Pathname#to_s called 29172 times.
61
61
  Pathname#<=> called 24963 times.
@@ -97,8 +97,10 @@ I've said this about Sprockets but this required two other gems to be updated as
97
97
  ## Status
98
98
 
99
99
  * Rust compilation is working
100
- * Methods are _most likely_ stable
101
- * Testers and developers are most welcome!
100
+ * Methods are stable
101
+ * Thoroughly tested
102
+ * Testers and developers are most welcome
103
+ * Windows & encoding support is underway!
102
104
 
103
105
  ## Installation
104
106
 
@@ -113,7 +115,7 @@ curl -sSf https://static.rust-lang.org/rustup.sh | sh
113
115
  Add this line to your application's Gemfile:
114
116
 
115
117
  ```ruby
116
- gem 'faster_path', '~> 0.2.3'
118
+ gem 'faster_path', '~> 0.3.1'
117
119
  ```
118
120
 
119
121
  And then execute:
@@ -147,6 +149,7 @@ Current methods implemented:
147
149
  | `FasterPath.del_trailing_separator` | `Pathname#del_trailing_separator` | 80.6% |
148
150
  | `FasterPath.directory?` | `Pathname#directory?` | 11.3% |
149
151
  | `FasterPath.entries` | `Pathname#entries` | 8.4% |
152
+ | `FasterPath.extname` | `File.extname` | 41.2% |
150
153
  | `FasterPath.has_trailing_separator?` | `Pathname#has_trailing_separator` | 67.6% |
151
154
  | `FasterPath.plus` | `Pathname#join` | 66.4% |
152
155
  | `FasterPath.plus` | `Pathname#plus` | 81.4% |
@@ -181,10 +184,9 @@ These will **not** be included by default in monkey-patches. Be cautious when u
181
184
  |---|---|
182
185
  | `FasterPath.dirname` | `File.dirname` |
183
186
  | `FasterPath.basename` | `File.basename` |
184
- | `FasterPath.extname` | `File.extname` |
185
187
 
186
188
  It's been my observation (and some others) that the Rust implementation of the C code for `File` has similar results but
187
- performance seems to vary based on CPU cache on possibly 64bit/32bit system environmnets. When these methods were initially written, and somewhat simplistic, they were faster than the C implementations on `File`. After the implementations have been perfected to match the behavior in Ruby they don't perform as well and are therefore not included by default when the monkey patch method `FasterPath.sledgehammer_everything!` is executed. If you don't want to pass the `WITH_REGRESSION` environment variable you can put any turthy parameter on the monkey patch method to include it.
189
+ performance seems to vary based on CPU cache on possibly 64bit/32bit system environments. When these methods were initially written, and somewhat simplistic, they were faster than the C implementations on `File`. After the implementations have been perfected to match the behavior in Ruby they don't perform as well and are therefore not included by default when the monkey patch method `FasterPath.sledgehammer_everything!` is executed.
188
190
 
189
191
  ## Getting Started with Development
190
192
 
@@ -205,13 +207,7 @@ Learn and share performance tips on the [wiki](https://github.com/danielpclark/f
205
207
 
206
208
  ### Building and running tests
207
209
 
208
- First, bundle the gem's development dependencies by running `bundle`.
209
-
210
- Then, build the rust code:
211
-
212
- ```sh
213
- rake build_src
214
- ```
210
+ First, bundle the gem's development dependencies by running `bundle`. Rust compilation is included in the current rake commands.
215
211
 
216
212
  FasterPath is tested with [The Ruby Spec Suite](https://github.com/ruby/spec) to ensure it is compatible with the
217
213
  native implementation, and also has its own test suite testing its monkey-patching and refinements functionality.
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
- require 'fileutils'
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+ require 'thermite/tasks'
4
4
 
5
5
  desc 'System Details'
6
6
  task :sysinfo do
@@ -24,6 +24,8 @@ task :sysinfo do
24
24
  end
25
25
  end
26
26
 
27
+ thermite = Thermite::Tasks.new
28
+
27
29
  desc "Generate Contriburs.md Manifest"
28
30
  task :contrib do
29
31
  puts "Generating Contriburs.md Manifest"
@@ -61,36 +63,16 @@ task :libruby_debug do
61
63
  puts "libruby.so copied."
62
64
  end
63
65
 
64
- desc "Build Rust extension"
65
- task build_src: :libruby_release do
66
- puts "Building extension..."
67
- sh "cargo build --release"
68
- end
69
-
70
- desc "Clean up Rust build"
71
- task :clean_src do
72
- puts "Cleaning up build..."
73
- # Remove all but library file
74
- FileUtils.
75
- rm_rf(
76
- Dir.
77
- glob('target/release/*').
78
- keep_if do |f|
79
- !f[/\.(?:so|dll|dylib|deps)\z/]
80
- end
81
- )
66
+ desc 'Build + clean up Rust extension'
67
+ task build_lib: 'thermite:build' do
68
+ thermite.run_cargo 'clean'
82
69
  end
83
70
 
84
- desc "Build + clean up Rust extension"
85
- task build_lib: [:build_src, :clean_src] do
86
- puts "Completed build!"
87
- end
88
-
89
- desc "Code Quality Check"
71
+ desc 'Code Quality Check'
90
72
  task :lint do
91
73
  puts
92
- puts "Quality check starting..."
93
- sh "rubocop"
74
+ puts 'Quality check starting...'
75
+ sh 'rubocop'
94
76
  puts
95
77
  end
96
78
 
@@ -100,9 +82,8 @@ task cargo: :libruby_debug do
100
82
  end
101
83
 
102
84
  Rake::TestTask.new(minitest: :build_lib) do |t|
103
- t.libs << "test"
104
- t.libs << "lib"
105
- t.test_files = FileList['test/**/*_test.rb']
85
+ t.libs = %w[lib test]
86
+ t.pattern = 'test/**/*_test.rb'
106
87
  end
107
88
 
108
89
  task :init_mspec do |_t|
data/ext/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'thermite/tasks'
2
+
3
+ project_toplevel_dir = File.dirname(File.dirname(__FILE__))
4
+ Thermite::Tasks.new(cargo_project_path: project_toplevel_dir,
5
+ ruby_project_path: project_toplevel_dir)
6
+
7
+ task default: 'thermite:build'
data/faster_path.gemspec CHANGED
@@ -16,21 +16,22 @@ Gem::Specification.new do |spec|
16
16
  spec.files = [
17
17
  "Cargo.lock", "Cargo.toml", "Gemfile",
18
18
  "MIT-LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup",
19
- "ext/faster_path/extconf.rb", "faster_path.gemspec"
19
+ "ext/Rakefile", "faster_path.gemspec"
20
20
  ]
21
21
  spec.files += Dir['lib/**/*']
22
22
  spec.files += Dir['src/**/*']
23
23
 
24
- spec.extensions << "ext/faster_path/extconf.rb"
24
+ spec.extensions = ["ext/Rakefile"]
25
25
  spec.require_paths = ["lib"]
26
26
 
27
27
  spec.add_dependency "bundler", "~> 1.12"
28
28
  spec.add_dependency "rake", "~> 12.0"
29
+ spec.add_dependency "thermite", "~> 0.13.0"
29
30
  spec.add_development_dependency "read_source", "~> 0.2.6"
30
31
  spec.add_development_dependency "minitest", "~> 5.10"
31
32
  spec.add_development_dependency "minitest-reporters", "~> 1.1"
32
33
  spec.add_development_dependency "color_pound_spec_reporter", "~> 0.0.9"
33
- spec.add_development_dependency "rubocop", "~> 0.51"
34
+ spec.add_development_dependency "rubocop", "0.53"
34
35
  spec.add_development_dependency "stop_watch", "~> 1.0"
35
36
  if !ENV['CI'] && ENV['GRAPH']
36
37
  spec.add_development_dependency "gruff", "~> 0.7.0"
data/lib/faster_path.rb CHANGED
@@ -1,11 +1,16 @@
1
- require "faster_path/version"
1
+ require 'faster_path/version'
2
2
  require 'pathname'
3
- require 'faster_path/platform'
3
+ require 'thermite/config'
4
4
  require 'fiddle'
5
5
  require 'fiddle/import'
6
6
 
7
7
  module FasterPath
8
- FFI_LIBRARY = FasterPath::Platform.ffi_library()
8
+ FFI_LIBRARY = begin
9
+ toplevel_dir = File.dirname(__dir__)
10
+ config = Thermite::Config.new(cargo_project_path: toplevel_dir,
11
+ ruby_project_path: toplevel_dir)
12
+ config.ruby_extension_path
13
+ end
9
14
 
10
15
  Fiddle::Function.
11
16
  new(Fiddle.dlopen(FFI_LIBRARY)['Init_faster_pathname'], [], Fiddle::TYPE_VOIDP).
Binary file
@@ -10,7 +10,7 @@ module FasterPath
10
10
  pth = pth.to_path if pth.respond_to? :to_path
11
11
  raise TypeError unless pth.is_a?(String) && ext.is_a?(String)
12
12
  FasterPath.basename(pth, ext)
13
- end
13
+ end if !!ENV['WITH_REGRESSION']
14
14
 
15
15
  def self.extname(pth)
16
16
  pth = pth.to_path if pth.respond_to? :to_path
@@ -22,7 +22,7 @@ module FasterPath
22
22
  pth = pth.to_path if pth.respond_to? :to_path
23
23
  raise TypeError unless pth.is_a? String
24
24
  FasterPath.dirname(pth)
25
- end
25
+ end if !!ENV['WITH_REGRESSION']
26
26
  end
27
27
  end
28
28
 
@@ -96,8 +96,8 @@ module FasterPath
96
96
  end
97
97
  private_constant :MonkeyPatches
98
98
 
99
- def self.sledgehammer_everything!(include_file = !!ENV['WITH_REGRESSION'])
100
- MonkeyPatches._ruby_core_file! if include_file # SLOW; DON'T AUTO INCLUDE
99
+ def self.sledgehammer_everything!()
100
+ MonkeyPatches._ruby_core_file!
101
101
  MonkeyPatches._ruby_library_pathname!
102
102
  "CAUTION: Monkey patching effects everything! Be very sure you want this!"
103
103
  end
@@ -1,3 +1,3 @@
1
1
  module FasterPath
2
- VERSION = "0.2.6"
2
+ VERSION = "0.3.1"
3
3
  end
data/src/extname.rs CHANGED
@@ -1,13 +1,63 @@
1
- use path_parsing::extract_last_path_segment;
1
+ use path_parsing::SEP;
2
+ use std::str;
3
+
4
+ struct ExtnameCoords {
5
+ word: bool,
6
+ pred: bool,
7
+ dot: bool,
8
+ start: usize,
9
+ end: usize,
10
+ }
11
+
12
+ impl ExtnameCoords {
13
+ pub fn dec(&mut self) {
14
+ self.start -= 1;
15
+ if !self.word {
16
+ self.end -= 1;
17
+ }
18
+ }
19
+ }
2
20
 
3
21
  pub fn extname(pth: &str) -> &str {
4
- let name = extract_last_path_segment(pth);
22
+ let path = pth.as_bytes();
23
+ let mut extname = ExtnameCoords {
24
+ word: false,
25
+ pred: false,
26
+ dot: false,
27
+ start: path.len(),
28
+ end: path.len(),
29
+ };
5
30
 
6
- if let Some(dot_i) = name.rfind('.') {
7
- if dot_i > 0 && dot_i < name.len() - 1 && name[..dot_i].chars().rev().next().unwrap() != '.' {
8
- return &name[dot_i..]
31
+ for &item in path.iter().rev() {
32
+ if (item == b'.' && !extname.dot) || item == SEP {
33
+ if item == SEP && extname.word {
34
+ return ""
35
+ }
36
+
37
+ if !extname.pred {
38
+ extname.dec();
39
+ }
40
+
41
+ if extname.word {
42
+ extname.dot = true;
43
+ }
44
+ } else {
45
+ if extname.dot {
46
+ extname.pred = true;
47
+ break;
48
+ } else {
49
+ extname.word = true;
50
+ }
51
+
52
+ if !extname.pred {
53
+ extname.dec()
54
+ }
9
55
  }
10
56
  }
11
57
 
12
- ""
58
+ if !extname.pred {
59
+ return "";
60
+ }
61
+
62
+ str::from_utf8(&path[extname.start..extname.end]).unwrap_or("")
13
63
  }
data/src/path_parsing.rs CHANGED
@@ -1,5 +1,4 @@
1
1
  extern crate memchr;
2
- use self::memchr::memrchr;
3
2
  use std::path::MAIN_SEPARATOR;
4
3
  use std::str;
5
4
 
@@ -8,11 +7,6 @@ lazy_static! {
8
7
  pub static ref SEP_STR: &'static str = str::from_utf8(&[SEP]).unwrap();
9
8
  }
10
9
 
11
- pub fn extract_last_path_segment(path: &str) -> &str {
12
- let end = (last_non_sep_i(path) + 1) as usize;
13
- &path[memrchr(SEP, &path.as_bytes()[..end]).unwrap_or(0)..end]
14
- }
15
-
16
10
  // Returns the byte offset of the last byte preceding a MAIN_SEPARATOR.
17
11
  pub fn last_non_sep_i(path: &str) -> isize {
18
12
  last_non_sep_i_before(path, path.len() as isize - 1)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faster_path
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel P. Clark
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-03 00:00:00.000000000 Z
11
+ date: 2018-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '12.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thermite
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.13.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.13.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: read_source
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -98,16 +112,16 @@ dependencies:
98
112
  name: rubocop
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - "~>"
115
+ - - '='
102
116
  - !ruby/object:Gem::Version
103
- version: '0.51'
117
+ version: '0.53'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
- - - "~>"
122
+ - - '='
109
123
  - !ruby/object:Gem::Version
110
- version: '0.51'
124
+ version: '0.53'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: stop_watch
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -127,7 +141,7 @@ email:
127
141
  - 6ftdan@gmail.com
128
142
  executables: []
129
143
  extensions:
130
- - ext/faster_path/extconf.rb
144
+ - ext/Rakefile
131
145
  extra_rdoc_files: []
132
146
  files:
133
147
  - Cargo.lock
@@ -138,12 +152,12 @@ files:
138
152
  - Rakefile
139
153
  - bin/console
140
154
  - bin/setup
141
- - ext/faster_path/extconf.rb
155
+ - ext/Rakefile
142
156
  - faster_path.gemspec
143
157
  - lib/faster_path.rb
158
+ - lib/faster_path.so
144
159
  - lib/faster_path/optional/monkeypatches.rb
145
160
  - lib/faster_path/optional/refinements.rb
146
- - lib/faster_path/platform.rb
147
161
  - lib/faster_path/version.rb
148
162
  - src/basename.rs
149
163
  - src/chop_basename.rs
@@ -1,19 +0,0 @@
1
- require 'mkmf'
2
-
3
- have_header('Dummy Makefile')
4
-
5
- unless find_executable('cargo')
6
- puts "You need to have Rust installed for this gem to build natively."
7
- puts "Please install the latest nightly build:"
8
- puts
9
- puts "curl -sSf https://static.rust-lang.org/rustup.sh | sudo sh -s -- --channel=nightly"
10
- puts
11
- at_exit { puts "Exiting..."}
12
- end
13
-
14
- Dir.chdir(File.expand_path("../../", File.dirname(__FILE__))) do
15
- `rake build_src`
16
- `rake clean_src`
17
- end
18
-
19
- create_makefile('faster_path/dummy')
@@ -1,60 +0,0 @@
1
- module FasterPath
2
- module Platform
3
- class << self
4
- def ffi_library
5
- file = [
6
- lib_prefix,
7
- "faster_path.",
8
- lib_suffix
9
- ]
10
-
11
- File.join(rust_release, file.join())
12
- end
13
-
14
- def operating_system
15
- case host_os()
16
- when /linux|bsd|solaris/
17
- "linux"
18
- when /darwin/
19
- "darwin"
20
- when /mingw|mswin/
21
- "windows"
22
- else
23
- host_os()
24
- end
25
- end
26
-
27
- def lib_prefix
28
- case operating_system()
29
- when /windows/
30
- ''
31
- when /cygwin/
32
- 'cyg'
33
- else
34
- 'lib'
35
- end
36
- end
37
-
38
- def lib_suffix
39
- case operating_system()
40
- when /darwin/
41
- 'dylib'
42
- when /linux/
43
- 'so'
44
- when /windows|cygwin/
45
- 'dll'
46
- else
47
- 'so'
48
- end
49
- end
50
-
51
- def rust_release
52
- File.expand_path("../../target/release/", __dir__)
53
- end
54
-
55
- def host_os
56
- RbConfig::CONFIG['host_os'].downcase
57
- end
58
- end
59
- end
60
- end