yucky yucky
[source:ruby]
def os_path path
(*path.split(/\\|\//)).join( File::ALT_SEPARATOR || File::SEPARATOR )
end
[/source]
but sometimes it’s just gotta be done :(
[source:ruby]
def os_path path
(*path.split(/\\|\//)).join( File::ALT_SEPARATOR || File::SEPARATOR )
end
[/source]
but sometimes it’s just gotta be done :(
So there’s BlankSlate, and today tmm1 was doing something where he was delegating to Array, but wanted to actually have Array in the ancestor chain (for Class#===), so I came up with this:
[source:ruby]
def BS(superclass = nil, name = :BlankSlate)
klass = eval(”
class #{name} #{” < #{superclass}" if superclass}
end
#{name}
")
klass.class_eval {
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
}
klass
end
[/source]
And then he came up with the anti-eval solution:
[source:ruby]
class BlankSlate
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
end
def BlankSlate superclass = nil
if superclass
@blank_slates ||= {}
@blank_slates[superclass] ||= Class.new(superclass) do
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
end
else
BlankSlate
end
end
[/source]
refactors to:
[source:ruby]
class BlankSlate
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
end
def BlankSlate superclass = BlankSlate
@blank_slates ||= Hash.new do |h,k|
h[k] = Class.new(superclass) do
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
end
end
@blank_slates[superclass]
end
[/source]
But watch out!!!:
[source:ruby]
a = StrokeDB::LazyMappingArray.new([1,2,3]) # => [1, 2, 3]
Array === a # => true
Array.new(a) # => []
[a].flatten # => []
# The last two are ‘incorrect’ behaviour (probably work on rubinius,
# mind you, so did the delegation approach).
[/source]
Anyway, you get the idea, mix and match, (feedback?), whatever. Enjoy.
I know, I’m shouting, but there’s stuff to shout about!
I’ve hated ri for being so slow for so long. The new one is out!
I really recommend installing rdoc 2 and firing up ri for the first time. Now only the ‘first time’ takes a long time :D
It’s joyous, just under a second I can really put up with. Thanks to Eric, and I believe Ryan (as I seem to remember him mentioning his ri patch quite some time ago). :-)
Update: please see comments.
Take a look at this:
http://www.robbyonrails.com/articles/2008/03/24/dry-a-year-after-year
Surely this is completely pointless, I mean no rails programmer (or customer) died over 20 years ago. In the case of corporate copyright, the ‘owner’ is the company, so that could be a very very long time away.
http://en.wikipedia.org/wiki/Copyright#Duration
Legally this is pointless, it’s just aesthetic. Am I missing something?
I mean, so stern, using words like ‘guilty’ and ‘offense’…
I wonder if this is what planet argon charge their customers for. Three days of heavy “z0mg, you’re datez are teh wronGZ!!oneone”. I don’t know, but this kind of article, given the law behind it (and apparent lack of knowledge, or understanding) seems to scare me, personally. Can you trust these ‘consultancy’ firms to do what you need, as opposed to what they ‘think’. If I’d paid for someone to write 5 lines of code from my app, into what’s maybe 200 lines of config and cruft for a plugin, that makes only a minor aesthetic difference to a site, at the cost of some performance I might add, and potentially actually damaging copyright (by inconsistency), I’d be seriously seriously pissed.
Imagine archive.org lose you’re site, and you come up for a copyright case. The other side can prove they’ve been “ON IT” since 1995, and you’ve only got copyright for this year. Damn, that would really suck, if you care.
Of course, I do hope I’m missing something, and someone comes here to put me in my place.
Sorry to Robby, and Planet Argon, you just caught my eye. I’m sure the work they do is actually great, I mean, this is attention to code detail, so that’s something at least.
Here’s some stuff from the #ruby-lang mailinglist, with my replies inlined. It’s here because this kind of discussion often doesn’t go far on a mailinglist, but the response may have some validity to some people.
There really isn’t a secret list of “idioms” or rules that will save you from writing slow software. You really have to profile, and more than that, you need to focus on the right stuff, at the right time. I once found this hard to swallow, but I understand it, and it makes perfect sense. Being free of it, I now write better software, in a much shorter time frame. Oh and it’s easier to maintain too.
On 17 Mar 2008, at 18:08, Paul Brannan wrote:
On Tue, Mar 18, 2008 at 02:17:22AM +0900, Gerardo Santana G?mez Garrido wrote:
On Mon, Mar 17, 2008 at 12:42 PM, Marc Heiler wrote:
Anyone of you has a few hints on how to speed up ruby code?
(Note - not writing it, but running it ;-) )I only have a few hints, like 5… would love to extend it.
When generating text output, using StringIO is faster than using puts
This doesn’t make sense. One can easily call #puts on a StringIO
object.Do you have a concrete example/benchmark that demonstrates the
difference?Paul
This is a prime example of platform differences, hell, right up to the tool stack you’re running.
Generic ‘optimizations’ or hints in areas like this are not worth their salt. It’ll be different in one console / terminal / operating system to the next.
Moreover, a much better solution is to rebuffer the data, and specifically to coalesce it, in many cases (not all). This is not something that a generic “#freeze” “optimization” will give you. It’s a design decision, the overhead for which can be discovered by profiling if you spend some time thinking about what the numbers mean, and paying attention to how long you really think things should take. It doesn’t take long to realize that $stdout.puts is slow on a lot, but not *all* platforms. The simplest test is redirect to file, which on some setups, is *significantly* faster than terminal output (one is to memory, one is to disk, and yet…. go figure).
On 17 Mar 2008, at 15:06, Paul Brannan wrote:
On Mon, Mar 17, 2008 at 11:20:59PM +0900, Avdi Grimm wrote:
On Mon, Mar 17, 2008 at 9:22 AM, Ilan Berci coder68 @yahoo.com wrote:
There is only 1 hint:PROFILE IT!!!
+1
is +10 allowed?
I learned this lesson, and it is a serious lesson to learn.
There was a time when I had a feeling of perfection, where I wanted the code to be entirely as computationally optimal as possible all the time. The truth is, the stack underneath contains so much indirection and complexity, this is almost impossible to really attain, and indeed to do so, one has to profile anyway. The thing that solved this for me was including a notion of the development process, time, and simplicity into my notion of perfection.
> All discussions of performance tuning are meaningless without profiling numbers.
Profiling only tells you where performance bottlenecks are. It does
nothing for letting you know how to fix those bottlenecks. That’s where
benchmarks come into play.
Sure, but that’s algorithm and even state dependent. Maybe you can get 10% by adding a GC.start after loading a pile of data (this would be very app specific).
Benchmarks can lie (if poorly written, and it’s all too easy to write bad benchmarks), for example, on win32, it is possible to construct a benchmark under which the conditions will cause the ternary operator to appear faster than if else. Obviously, this is not *really* the case, moreover, it’s completely irrelevant unless you’re app is entirely bound by boolean logic operations. It’s also extremely difficult to use a profiling or benchmarking tool against, in pure ruby. Oh, and I’d put good money on it not having the same results on different versions or different interpreters.
There are limits to how low you can measure performance and a large portion of the discussed list falls into that category. It also seems to fall in to the category of stuff that is:
If you really want to continue on that list, you’ll want to include stuff like the following (which I don’t really agree with as good ideas to spread across the board):
These all show up in micro-benchmarks for sure. They don’t necessarily (in fact, “very often”) show up as real sources of poor performance in production code, unless you have very small units (in which case, good for you :-D). Poor performance in common application code tends to come from complexity most often. In some areas (heavier I/O code is maybe the most common?) you may need to add complexity, but it’s often possible to provide a drop-in piece of indirection (off the top of my head: cache, coalesce, un-block, drop threaded complexity, buffer, *increase buffer sizes*, and so on).
There was someone talking about ERB#new. That’s ERB.new… and for performance, Erubis is often faster, so there’s no real need to do much profiling there, as someone’s done it for you, as one other example of design change leading the real win.
Design change is really what has a significant effect on performance, in most all cases. Very few ‘generic’ things like concat vs. + for strings (which is pretty clear when profiling) really give you meaningful gains, although it does happen (this was a ~10,000 page pdf being generated iirc):

This shows nasty saw-tooth ram usage, and poor memory performance. That red line is the kernel sorting out memory.

This was actually something pretty equivalent to s/” + “/” << “/g for this particular case, this will not come along very often
Here’s something I used to replace ‘builder’ for something that needed more speed:
[source:ruby]
X = Object.new
def X.[](name, att = nil, inner = nil)
inner ? att ? “< #{name}#{att}>#{inner}” : “< #{name}>#{inner}” : att ? “< #{name}#{att} />” : “< #{name}/>”
end
[/source]
Clearly the api is not the same, and it doesn’t do nearly the same stuff. It’s an extreme example. However, it smashes over everything else for performance (when combined with concat, not +, clearly), so we no longer have to care. Maintenance is not proving any kind of problem either, as we don’t use it everywhere. We use this *only* where we need to, which in our case was a very long XML generation (in excess of 20mb with very high node count).
The example has the following different profiles, which I would strongly argue simply could not be obtained by sticking with a lib with builders features (that is, this isn’t builders fault, nor is the above a replacement for builder. It’s one-time build and use code for a few cases where it’s needed):
Total Time: 4.452756
%total %self total self wait child calls Name
--------------------------------------------------------------------------------
100.00% 0.00% 4.45 0.00 0.00 4.45 0 Global#[No method] (prof_vs_frozen.rb:55} prof_vs_frozen.rb:55
4.45 2.01 0.00 2.44 1/1 Integer#times
——————————————————————————–
4.45 2.01 0.00 2.44 1/1 Global#[No method]
100.00% 45.16% 4.45 2.01 0.00 2.44 1 Integer#times (ruby_runtime:0} ruby_runtime:0
2.01 2.01 0.00 0.00 200000/200000 <Object::Object>#[]
0.22 0.22 0.00 0.00 100000/100000 Array#<<
0.22 0.22 0.00 0.00 100000/100000 String#==
——————————————————————————–
2.01 2.01 0.00 0.00 200000/200000 Integer#times
45.05% 45.05% 2.01 2.01 0.00 0.00 200000 <Object::Object>#[] (prof_vs_frozen.rb:44} prof_vs_frozen.rb:44
——————————————————————————–
0.22 0.22 0.00 0.00 100000/100000 Integer#times
4.92% 4.92% 0.22 0.22 0.00 0.00 100000 String#== (ruby_runtime:0} ruby_runtime:0
——————————————————————————–
0.22 0.22 0.00 0.00 100000/100000 Integer#times
4.87% 4.87% 0.22 0.22 0.00 0.00 100000 Array#<< (ruby_runtime:0} ruby_runtime:0
Thread ID: 214780
Total Time: 116.686341
%total %self total self wait child calls Name
——————————————————————————–
100.00% 0.00% 116.69 0.00 0.00 116.69 0 Global#[No method] (prof_vs_frozen.rb:85} prof_vs_frozen.rb:85
116.69 0.64 0.00 116.04 1/1 Integer#times
——————————————————————————–
116.69 0.64 0.00 116.04 1/1 Global#[No method]
100.00% 0.55% 116.69 0.64 0.00 116.04 1 Integer#times (ruby_runtime:0} ruby_runtime:0
116.04 6.50 0.00 109.55 100000/100000 Builder::XmlBase#method_missing
——————————————————————————–
116.04 6.50 0.00 109.55 100000/100000 Integer#times
99.45% 5.57% 116.04 6.50 0.00 109.55 100000 Builder::XmlBase#method_missing (/opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:37} /opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:37
0.22 0.22 0.00 0.00 100000/200000 Kernel#kind_of?
2.12 1.70 0.00 0.42 200000/400000 Builder::XmlBase#_newline
39.69 2.32 0.00 37.37 100000/200000 Builder::XmlMarkup#_start_tag
2.16 1.66 0.00 0.49 100000/600000 Array#each
61.31 1.56 0.00 59.75 100000/100000 Builder::XmlBase#_nested_structures
0.22 0.22 0.00 0.00 100000/200000 NilClass#nil?
1.48 0.97 0.00 0.51 100000/200000 Builder::XmlMarkup#_end_tag
2.13 1.71 0.00 0.42 200000/400000 Builder::XmlBase#_indent
0.22 0.22 0.00 0.00 100000/200000 Array#first
——————————————————————————–
39.69 2.32 0.00 37.37 100000/200000 Builder::XmlBase#method_missing
39.77 2.30 0.00 37.47 100000/200000 Builder::XmlBase#method_missing-1
68.10% 3.96% 79.46 4.62 0.00 74.84 200000 Builder::XmlMarkup#_start_tag (/opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlmarkup.rb:286} /opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlmarkup.rb:286
0.56 0.56 0.00 0.00 200000/600000 Symbol#to_s
0.93 0.93 0.00 0.00 400000/800000 String#< <
73.35 3.39 0.00 69.96 200000/200000 Builder::XmlMarkup#_insert_attributes
--------------------------------------------------------------------------------
73.35 3.39 0.00 69.96 200000/200000 Builder::XmlMarkup#_start_tag
62.86% 2.91% 73.35 3.39 0.00 69.96 200000 Builder::XmlMarkup#_insert_attributes (/opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlmarkup.rb:299} /opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlmarkup.rb:299
0.42 0.42 0.00 0.00 200000/600000 Array#each
0.44 0.44 0.00 0.00 200000/200000 Kernel#nil?
69.10 3.75 0.00 65.35 200000/200000 Hash#each
--------------------------------------------------------------------------------
69.10 3.75 0.00 65.35 200000/200000 Builder::XmlMarkup#_insert_attributes
59.22% 3.21% 69.10 3.75 0.00 65.35 200000 Hash#each (ruby_runtime:0} ruby_runtime:0
62.90 3.13 0.00 59.76 200000/200000 Builder::XmlMarkup#_attr_value
0.54 0.54 0.00 0.00 200000/600000 Symbol#to_s
0.49 0.49 0.00 0.00 200000/800000 String#<<
1.43 1.01 0.00 0.42 200000/200000 Enumerable#member?
--------------------------------------------------------------------------------
62.90 3.13 0.00 59.76 200000/200000 Hash#each
53.90% 2.68% 62.90 3.13 0.00 59.76 200000 Builder::XmlMarkup#_attr_value (/opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlmarkup.rb:310} /opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlmarkup.rb:310
0.44 0.44 0.00 0.00 200000/400000 Module#===
58.89 1.83 0.00 57.07 200000/200000 Builder::XmlBase#_escape_quote
0.43 0.43 0.00 0.00 200000/200000 String#to_s
--------------------------------------------------------------------------------
61.31 1.56 0.00 59.75 100000/100000 Builder::XmlBase#method_missing
52.55% 1.34% 61.31 1.56 0.00 59.75 100000 Builder::XmlBase#_nested_structures (/opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:132} /opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:132
0.21 0.21 0.00 0.00 100000/200000 Fixnum#-
59.33 0.97 0.00 58.36 100000/100000 Proc#call
0.21 0.21 0.00 0.00 100000/200000 Fixnum#+
--------------------------------------------------------------------------------
59.33 0.97 0.00 58.36 100000/100000 Builder::XmlBase#_nested_structures
50.84% 0.83% 59.33 0.97 0.00 58.36 100000 Proc#call (ruby_runtime:0} ruby_runtime:0
58.36 6.57 0.00 51.79 100000/100000 Builder::XmlBase#method_missing-1
--------------------------------------------------------------------------------
58.89 1.83 0.00 57.07 200000/200000 Builder::XmlMarkup#_attr_value
50.47% 1.57% 58.89 1.83 0.00 57.07 200000 Builder::XmlBase#_escape_quote (/opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:118} /opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:118
0.65 0.65 0.00 0.00 200000/200000 String#gsub
56.41 1.30 0.00 55.12 200000/200000 Builder::XmlBase#_escape
--------------------------------------------------------------------------------
58.36 6.57 0.00 51.79 100000/100000 Proc#call
50.02% 5.63% 58.36 6.57 0.00 51.79 100000 Builder::XmlBase#method_missing-1 (/opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:37} /opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:37
0.22 0.22 0.00 0.00 100000/200000 Kernel#kind_of?
2.12 1.70 0.00 0.42 200000/400000 Builder::XmlBase#_newline
39.77 2.30 0.00 37.47 100000/200000 Builder::XmlMarkup#_start_tag
2.18 1.69 0.00 0.49 100000/600000 Array#each
3.43 1.56 0.00 1.87 100000/100000 Builder::XmlBase#_nested_structures-1
0.22 0.22 0.00 0.00 100000/200000 NilClass#nil?
1.49 0.98 0.00 0.51 100000/200000 Builder::XmlMarkup#_end_tag
2.13 1.71 0.00 0.42 200000/400000 Builder::XmlBase#_indent
0.22 0.22 0.00 0.00 100000/200000 Array#first
--------------------------------------------------------------------------------
56.41 1.30 0.00 55.12 200000/200000 Builder::XmlBase#_escape_quote
48.35% 1.11% 56.41 1.30 0.00 55.12 200000 Builder::XmlBase#_escape (/opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:114} /opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:114
55.12 2.26 0.00 52.85 200000/200000 String#to_xs
--------------------------------------------------------------------------------
55.12 2.26 0.00 52.85 200000/200000 Builder::XmlBase#_escape
47.24% 1.94% 55.12 2.26 0.00 52.85 200000 String#to_xs (/opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xchar.rb:110} /opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xchar.rb:110
0.59 0.59 0.00 0.00 200000/200000 Array#join
51.68 3.45 0.00 48.23 200000/200000 Array#map
0.59 0.59 0.00 0.00 200000/200000 String#unpack
--------------------------------------------------------------------------------
51.68 3.45 0.00 48.23 200000/200000 String#to_xs
44.29% 2.96% 51.68 3.45 0.00 48.23 200000 Array#map (ruby_runtime:0} ruby_runtime:0
48.23 19.46 0.00 28.77 600000/600000 Fixnum#xchr
--------------------------------------------------------------------------------
48.23 19.46 0.00 28.77 600000/600000 Array#map
41.33% 16.68% 48.23 19.46 0.00 28.77 600000 Fixnum#xchr (/opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xchar.rb:93} /opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xchar.rb:93
11.46 7.74 0.00 3.72 1800000/1800000 Kernel#===
1.26 1.26 0.00 0.00 600000/600000 Fixnum#<
1.56 1.56 0.00 0.00 600000/600000 Integer#chr
7.86 5.28 0.00 2.58 1200000/1200000 Hash#[]
6.63 4.10 0.00 2.53 600000/600000 Range#===
--------------------------------------------------------------------------------
11.46 7.74 0.00 3.72 1800000/1800000 Fixnum#xchr
9.82% 6.63% 11.46 7.74 0.00 3.72 1800000 Kernel#=== (ruby_runtime:0} ruby_runtime:0
3.72 3.72 0.00 0.00 1800000/2600000 Fixnum#==
--------------------------------------------------------------------------------
7.86 5.28 0.00 2.58 1200000/1200000 Fixnum#xchr
6.73% 4.53% 7.86 5.28 0.00 2.58 1200000 Hash#[] (ruby_runtime:0} ruby_runtime:0
2.58 2.58 0.00 0.00 1200000/1200000 Hash#default
--------------------------------------------------------------------------------
6.63 4.10 0.00 2.53 600000/600000 Fixnum#xchr
5.69% 3.52% 6.63 4.10 0.00 2.53 600000 Range#=== (ruby_runtime:0} ruby_runtime:0
2.53 2.53 0.00 0.00 1200000/1200000 Fixnum#<=>
--------------------------------------------------------------------------------
3.72 3.72 0.00 0.00 1800000/2600000 Kernel#===
0.84 0.84 0.00 0.00 400000/2600000 Builder::XmlBase#_newline
0.84 0.84 0.00 0.00 400000/2600000 Builder::XmlBase#_indent
4.63% 4.63% 5.40 5.40 0.00 0.00 2600000 Fixnum#== (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.42 0.42 0.00 0.00 200000/600000 Enumerable#member?
2.16 1.66 0.00 0.49 100000/600000 Builder::XmlBase#method_missing
2.18 1.69 0.00 0.49 100000/600000 Builder::XmlBase#method_missing-1
0.42 0.42 0.00 0.00 200000/600000 Builder::XmlMarkup#_insert_attributes
4.44% 3.59% 5.18 4.19 0.00 0.99 600000 Array#each (ruby_runtime:0} ruby_runtime:0
0.42 0.42 0.00 0.00 200000/400000 Module#===
0.56 0.56 0.00 0.00 200000/200000 Hash#merge!
--------------------------------------------------------------------------------
2.13 1.71 0.00 0.42 200000/400000 Builder::XmlBase#method_missing
2.13 1.71 0.00 0.42 200000/400000 Builder::XmlBase#method_missing-1
3.65% 2.93% 4.26 3.42 0.00 0.84 400000 Builder::XmlBase#_indent (/opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:127} /opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:127
0.84 0.84 0.00 0.00 400000/2600000 Fixnum#==
--------------------------------------------------------------------------------
2.12 1.70 0.00 0.42 200000/400000 Builder::XmlBase#method_missing
2.12 1.70 0.00 0.42 200000/400000 Builder::XmlBase#method_missing-1
3.63% 2.91% 4.24 3.40 0.00 0.84 400000 Builder::XmlBase#_newline (/opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:122} /opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:122
0.84 0.84 0.00 0.00 400000/2600000 Fixnum#==
--------------------------------------------------------------------------------
3.43 1.56 0.00 1.87 100000/100000 Builder::XmlBase#method_missing-1
2.94% 1.34% 3.43 1.56 0.00 1.87 100000 Builder::XmlBase#_nested_structures-1 (/opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:132} /opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlbase.rb:132
0.22 0.22 0.00 0.00 100000/200000 Fixnum#-
1.44 1.21 0.00 0.22 100000/100000 Proc#call-1
0.21 0.21 0.00 0.00 100000/200000 Fixnum#+
--------------------------------------------------------------------------------
1.48 0.97 0.00 0.51 100000/200000 Builder::XmlBase#method_missing
1.49 0.98 0.00 0.51 100000/200000 Builder::XmlBase#method_missing-1
2.55% 1.67% 2.98 1.95 0.00 1.03 200000 Builder::XmlMarkup#_end_tag (/opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlmarkup.rb:294} /opt/local/lib/ruby/gems/1.8/gems/builder-2.1.2/lib/builder/xmlmarkup.rb:294
0.55 0.55 0.00 0.00 200000/600000 Symbol#to_s
0.48 0.48 0.00 0.00 200000/800000 String#<<
--------------------------------------------------------------------------------
2.58 2.58 0.00 0.00 1200000/1200000 Hash#[]
2.21% 2.21% 2.58 2.58 0.00 0.00 1200000 Hash#default (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
2.53 2.53 0.00 0.00 1200000/1200000 Range#===
2.17% 2.17% 2.53 2.53 0.00 0.00 1200000 Fixnum#<=> (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.93 0.93 0.00 0.00 400000/800000 Builder::XmlMarkup#_start_tag
0.48 0.48 0.00 0.00 200000/800000 Builder::XmlMarkup#_end_tag
0.49 0.49 0.00 0.00 200000/800000 Hash#each
1.63% 1.63% 1.90 1.90 0.00 0.00 800000 String#<< (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.56 0.56 0.00 0.00 200000/600000 Builder::XmlMarkup#_start_tag
0.55 0.55 0.00 0.00 200000/600000 Builder::XmlMarkup#_end_tag
0.54 0.54 0.00 0.00 200000/600000 Hash#each
1.41% 1.41% 1.64 1.64 0.00 0.00 600000 Symbol#to_s (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
1.56 1.56 0.00 0.00 600000/600000 Fixnum#xchr
1.34% 1.34% 1.56 1.56 0.00 0.00 600000 Integer#chr (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
1.44 1.21 0.00 0.22 100000/100000 Builder::XmlBase#_nested_structures-1
1.23% 1.04% 1.44 1.21 0.00 0.22 100000 Proc#call-1 (ruby_runtime:0} ruby_runtime:0
0.22 0.22 0.00 0.00 100000/100000 String#==
--------------------------------------------------------------------------------
1.43 1.01 0.00 0.42 200000/200000 Hash#each
1.23% 0.87% 1.43 1.01 0.00 0.42 200000 Enumerable#member? (ruby_runtime:0} ruby_runtime:0
0.42 0.42 0.00 0.00 200000/600000 Array#each
--------------------------------------------------------------------------------
1.26 1.26 0.00 0.00 600000/600000 Fixnum#xchr
1.08% 1.08% 1.26 1.26 0.00 0.00 600000 Fixnum#< (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.44 0.44 0.00 0.00 200000/400000 Builder::XmlMarkup#_attr_value
0.42 0.42 0.00 0.00 200000/400000 Array#each
0.74% 0.74% 0.86 0.86 0.00 0.00 400000 Module#=== (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.65 0.65 0.00 0.00 200000/200000 Builder::XmlBase#_escape_quote
0.56% 0.56% 0.65 0.65 0.00 0.00 200000 String#gsub (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.59 0.59 0.00 0.00 200000/200000 String#to_xs
0.50% 0.50% 0.59 0.59 0.00 0.00 200000 Array#join (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.59 0.59 0.00 0.00 200000/200000 String#to_xs
0.50% 0.50% 0.59 0.59 0.00 0.00 200000 String#unpack (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.56 0.56 0.00 0.00 200000/200000 Array#each
0.48% 0.48% 0.56 0.56 0.00 0.00 200000 Hash#merge! (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.22 0.22 0.00 0.00 100000/200000 Builder::XmlBase#method_missing
0.22 0.22 0.00 0.00 100000/200000 Builder::XmlBase#method_missing-1
0.38% 0.38% 0.44 0.44 0.00 0.00 200000 Kernel#kind_of? (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.22 0.22 0.00 0.00 100000/200000 Builder::XmlBase#method_missing
0.22 0.22 0.00 0.00 100000/200000 Builder::XmlBase#method_missing-1
0.38% 0.38% 0.44 0.44 0.00 0.00 200000 NilClass#nil? (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.22 0.22 0.00 0.00 100000/200000 Builder::XmlBase#method_missing
0.22 0.22 0.00 0.00 100000/200000 Builder::XmlBase#method_missing-1
0.38% 0.38% 0.44 0.44 0.00 0.00 200000 Array#first (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.44 0.44 0.00 0.00 200000/200000 Builder::XmlMarkup#_insert_attributes
0.37% 0.37% 0.44 0.44 0.00 0.00 200000 Kernel#nil? (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.43 0.43 0.00 0.00 200000/200000 Builder::XmlMarkup#_attr_value
0.37% 0.37% 0.43 0.43 0.00 0.00 200000 String#to_s (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.21 0.21 0.00 0.00 100000/200000 Builder::XmlBase#_nested_structures
0.22 0.22 0.00 0.00 100000/200000 Builder::XmlBase#_nested_structures-1
0.37% 0.37% 0.43 0.43 0.00 0.00 200000 Fixnum#- (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.21 0.21 0.00 0.00 100000/200000 Builder::XmlBase#_nested_structures
0.21 0.21 0.00 0.00 100000/200000 Builder::XmlBase#_nested_structures-1
0.36% 0.36% 0.42 0.42 0.00 0.00 200000 Fixnum#+ (ruby_runtime:0} ruby_runtime:0
--------------------------------------------------------------------------------
0.22 0.22 0.00 0.00 100000/100000 Proc#call-1
0.19% 0.19% 0.22 0.22 0.00 0.00 100000 String#== (ruby_runtime:0} ruby_runtime:0
forewarning: anyone who goes off about builders complexity or use of method_missing being the source of, well, anyones “problems” doesn’t get it, and I will treat your comments with sufficient disregard. The point is the profile difference is a design impact, not an implementation detail. And yeah, I know that looks broken with the box, i’m accepting patches, yeah :-P
In the above example, I also went through memoize and a number of other ideas, but that turned out to be a lot slower than just building the strings as simply as possible using interpolation, for strings of this length, being used in this manner. It’s probably important to note that we were building many small nodes. Oh, and I should also note that it may not be so good for very large nodes.
Also, it’s the user experience that counts, so measure based on what the users are actually doing, not the slowest performing method or some such metric. You could spend all the time in the world building up lists of what operator is slower than what under what conditions or what this is faster than what that. If that’s you, seriously, drop it. It’s bad for you, and your code.
Mood: seriously annoyed.
Sorry to all of you to whom I have mentioned my upcoming ojbect_protocol release, that are hoping it to come soon.
As much as I would like to release it soon, I do not have the time to finish off the specs, docs and examples any time soon. I refuse to release my first major lib without a good helping of all of the above, so for now, it’s either offer genuine assistance, or wait.
time time time time time time TIME TIME TIME TIME TIME TIME TIME TIME
- if only it was as abundant as that
So in the recent Textmate update, the ruby bundle run command just had the following line added:
#!bin/sh
And the result is, raggi finds out that his Leopard account doesn’t seem to load the environment.plist file. I spent a couple of hours searching round, triple checking paths etc. To find no evidence of this file actually being loaded. If there’s anyone out there who can shed some light on this, that would be great…
Update
The issue was I had an old entry to TM_RUBY in my Preferences…->Advanced->Shell Variables. Remove that, and suddenly environment.plist seems to be being used. The entry in preferences was correct too, it just seems to do very bad things to certain textmate scripts. :(
There’s a “problem” with the current version of rubygems that’s causing somewhat of a FAQ, that as far as I can see, Google doesn’t index too well, so this post is for you, those people that find yourselves here via Google, at least until the problem is at least well known or the procedures change.
The relevant entry in the change log is this one:
Executable stubs can now be installed to match ruby’s name, so if ruby is installed as ‘ruby18’, foo_exec will be installed as ‘foo_exec18’
This can be found on Eric Hodels blog.
The current version of gems (1.0.1) installs the gem command as gem18 if your ruby is installed as ruby18.
For now, the fact that the upgrade via “gem update –system” is not doing anything with the old ‘gem’ command, is causing quite a few people to come into the ruby channel complaining about the following error:
gem:23: uninitialized constant Gem::Gem Runner (NameError)
You want to remove your old gem command (found at `which gem`) (i.e. rm `which gem`) and then link or copy the new gem command (likely gem18) to gem.
Anyway, this post is only this long so that it gains a high enough relevance for google to bother indexing it, with the goal of helping out a few of you folks until one of the many possible more permanent resolutions comes about.
Overall, the 1.0.1 release is a great release, seeing a lot of enhancements in rubygems that personally, I’m really happy to see. Thanks for all the hard work Eric, Chad and everyone else involved.
ttfn!
Update:
As it seems to have not been clear to some, on Debian, it may well (n.b. may well != will) be gem1.8, as your ruby may be ruby1.8.
If you need to know which it is, do the following:
ls -la `which ruby`
And this should tell you which ruby file you’re “ruby” is linked to, and where that link is located.
It looks like I’m getting quite involved with building ruby on MinGW now.
One of the things that is starting to come up is some common code that breaks when moving between the two builds, and one particular example came up tonight:
[source:ruby]
RUBY_PLATFORM =~ /mswin/
[/source]
What I’m going to have to look into (or hopefully told) is how RubyGems is now splitting platforms (I seem to remember Eric Hodel has posted about this elsewhere and recently worked on it). I’m hoping that can / is exposed to make life easier for a lot of developers. I know zenspider often sets WINDOZE, I don’t remember the test he most often uses for it though.
Outside / without rubygems though, it needs to generally be:
[source:ruby]
RUBY_PLATFORM =~ /mswin|mingw/
[/source]
Particularly when using things like signals or device paths.
Summary: sorry for late moderation of some peoples comments, this post is a rant about spam, and i’ll be off wordpress as soon as I can be.
I haven’t been through the comment moderation list in over a month. Shame on me.
Sorry to those who’s comments were not posted until far later than they should have been.
Spam, spam, bloody spam. </rant>
Time for a Javascript based comment submission I think, and to move away from run of the mill blogging software, because there are few other solutions these days that actually seem to work, and in some ways, I have better things to do with my time than sift this crap.
Right ok. This is probably a really crap idea (almost worthy of an obscenity? you decide.), but I want to start filtering all urls in my comments into a list I’m going to publish as a DNS blacklist, which I will start distributing to anyone who desires it.
Screw you spamming gits. I’m going to filter all of my google searches from now on. Anything with your crap or something within a link catchers eye of your crap is not going to go near me.
What if comments can be flagged as comments for google, and google stop ranking sites by links left in comments?
In fact, links in comments should gain -ve weight, and the people should just be told.
I want a box on my site where i can publicly shame these fuckers and the google results will actually respond in a decent manner.
Sadly, that’s not possible because it’s subject to an attack by it’s very nature, with that you could demote the rank of competing sites. cryface.
Still I want to publicly shame them, but in order to not help them it must be private. Maybe I should e-mail _why and ask him to hide a spam site ban list in hoodwink.d for me…
I guess the rant wasn’t really over. Anyone else feel the pain?