From: Hiroshi Shirosaki Date: 2011-11-18T11:56:44+09:00 Subject: [ruby-core:41124] [ruby-trunk - Feature #5562] Improvement of Windows IO performance Issue #5562 has been updated by Hiroshi Shirosaki. At TestOpen3#test_capture3_flip error, ERROR_SHARING_VIOLATION occurs because ruby tries to unlink a temp file while new process by capture3 are running. New process seems to have reference to the temp file. In addition, some other temp files are left undeleted after make test-all is finished. Would it be possible to delete temp files at another time such as at_exit? This patch is an idea. diff --git a/lib/tempfile.rb b/lib/tempfile.rb index 22401b0..9344b5f 100644 --- a/lib/tempfile.rb +++ b/lib/tempfile.rb @@ -80,6 +80,13 @@ require 'thread' # mutex. class Tempfile < DelegateClass(File) MAX_TRY = 10 # :nodoc: + UNDELETED_FILES = [] + # Try to unlink undeleted temp files on Windows + at_exit do + UNDELETED_FILES.each do |path| + (File.unlink(path) if File.exist?(path)) rescue nil + end + end include Dir::Tmpname # call-seq: @@ -235,6 +242,7 @@ class Tempfile < DelegateClass(File) @tmpname = nil rescue Errno::EACCES # may not be able to unlink on Windows; just ignore + UNDELETED_FILES << path end end alias delete unlink @@ -276,7 +284,12 @@ class Tempfile < DelegateClass(File) # keep this order for thread safeness if path - File.unlink(path) if File.exist?(path) + begin + File.unlink(path) if File.exist?(path) + rescue Errno::EACCES + # may not be able to unlink on Windows; just ignore + UNDELETED_FILES << path + end end STDERR.print "done\n" if $DEBUG ---------------------------------------- Feature #5562: Improvement of Windows IO performance http://redmine.ruby-lang.org/issues/5562 Author: Hiroshi Shirosaki Status: Assigned Priority: Normal Assignee: Usaku NAKAMURA Category: core Target version: =begin I suggest a patch to improve Windows IO performance. Ruby's text mode IO is much slower than binary mode. On Windows text mode is default, so Windows IO is slow. I assume that's mainly because of CRLF linefeed code conversion. My idea to improve IO performance is as below. - Change default linefeed conversion from Universal newline to CRLF newline on Windows - Use binary mode process with OS's text mode if only CRLF conversion is needed - Use Ruby's text mode with universal newline conversion if encoding conversion is needed Although that causes io.c code to be more complicated, IO with CRLF conversion performance seems to be improved much. I confirmed "make test-all TEST=ruby" have been passed. There was 3 errors, but ruby without this patch had same errors. I think this patch doesn't affect other OS. Line endings of "p" or "puts" writing is LF on trunk, but CRLF on 1.8.7 or 1.9.2. This patch reverts to CRLF. Here is #1332 benchmark test and results. time = [Time.new] c = '' 'aaaa'.upto('zzzz') {|e| c << e} 4.times { c << c } time << Time.new File.open('out.file','w') { |f| f.write(c) } time << Time.new c = File.open('out.file','r') { |f| f.read } time << Time.new 0.upto(time.size - 2) {|i| p "#{i} #{time[i+1]-time[i]}" } - Result ruby 1.8.7 (2011-06-30 patchlevel 352) [i386-mingw32] "0 0.78125" "1 0.6875" "2 0.5625" ruby 2.0.0dev (2011-11-03) [i386-mingw32] "0 0.59375" "1 1.09375" "2 1.296875" ruby 2.0.0dev (2011-11-03 trunk 33615) [i386-mingw32] with this patch "0 0.625" "1 0.65625" "2 0.34375" =end -- http://redmine.ruby-lang.org