Surprise 10min Benchmark: eval, class_eval, instance_eval, define_method, bind

Posted over 7 years back at Wood for the Trees

What is the fastest way to dynamically define a method? define_method? class_eval? instance_eval? With strings or procs? Maybe we can pull out some arcane magic and use instance_method and bind (depending on what we want to do).

We all need to use some kind of eval at some point and, while it will not usually effect performance when used sparingly, sometimes it just has to make a serious appearance. When I saw how slow RSpec is in comparison to the venerable Test::Unit, I discovered the way it handles its contexts: each one is individually instance_eval’d into an empty ContextEvalModule. It isn’t the only reason for being slower, but it is one and one which can really mount up on big projects.

So, moving on from RSpec, Test::Unit and my baseline, MicroTest (see previous post), I became perversely interested in benchmarking all the ways of doing it and found some surprises.

Results (Ruby 1.8.4)

                            user     system      total        real
eval/str              112.540000   0.060000 112.600000 (112.615607)
instance_eval/str      99.510000   0.040000  99.550000 ( 99.564661)
class_eval/str        112.750000   0.060000 112.810000 (112.824374)
instance_eval/proc     56.750000   0.040000  56.790000 ( 56.802483)
class_eval/proc        56.440000   0.020000  56.460000 ( 56.464818)
define_method/class   112.420000   0.060000 112.480000 (112.489430)
define_method/send    111.540000   0.050000 111.590000 (111.610502)
def/unbind/bind        73.750000   0.060000  73.810000 ( 73.875800)
def                    52.670000   0.030000  52.700000 ( 52.705886)
method/bind            13.520000   0.010000  13.530000 ( 13.523194)

Analysis

I put it roughly in the order which I originally expected, with the slowest at the top.

The first thing that stunned me was the speed of define_method. It’s as slow as a snail. It’s practically eval, despite using a proc. I’ve been using it in preference before, thinking it was faster than any of the evals (proc or string). Apparently not.

The second revelation was how proc-based evals are about 50% faster than a def/unbind/bind cycle, which only has def as the evaluating part. That any eval is close to def is simply surprising. The instance_eval variety is the one used by RSpec, so I guess they picked the best one already.

The third shock was how slow def is! Granted, this is a lot of iterations, but it should be quicker than that, surely?

So it seems pretty plain that method unbinding as a tuning technique is rubbish, despite not evaluating anything, whereas a proc-based instance_eval or simple def are the clear winners.

But wait… what about Ruby 1.8.5?

Seeing the decrepitude of define_method made me wonder about the latest release of Ruby. I downloaded it, compiled it, got it working and ran the same bench:

Results (Ruby 1.8.5)

                            user     system      total        real
instance_eval/str     109.620000   0.050000 109.670000 (109.685393)
class_eval/str        113.840000   0.060000 113.900000 (113.910749)
eval/str              114.520000   0.060000 114.580000 (114.596238)
define_method/class    70.220000   0.040000  70.260000 ( 70.264506)
define_method/send     68.030000   0.040000  68.070000 ( 68.066688)
def/unbind/bind        73.690000   0.030000  73.720000 ( 73.741549)
instance_eval/proc     59.050000   0.030000  59.080000 ( 59.084445)
class_eval/proc        59.530000   0.030000  59.560000 ( 59.566885)
def                    52.870000   0.030000  52.900000 ( 52.895184)
method/bind            12.470000   0.010000  12.480000 ( 12.484069)

Anaylsis

I guess they fixed the problem and more besides. define_method is now marginally faster than def/unbind/bind (which has not budged an inch). I think I’ll continue to take the performance hit on define_method with 1.8.4, knowing I’ll want to upgrade later in the future and not change techniques.

The old recommendations hold true

  • instance_eval with a proc for class, instance or singleton evaluation
  • instance_eval for changing proc bindings
  • define_method for converting procs into methods
  • def for everything else
  • eval when you really know you need it

Note: These findings are only for def meth; true; end and may vary in complex cases.

Benchmark Code

require 'benchmark'

class A; def meth1; true; end; end

# defining using eval/class/instance
str = "def meth2; true; end"
a_binding = A.send(:binding)

# proc for class/instance
proc1 = Proc.new { def meth2; true; end }

# proc for define_method
$proc2 = Proc.new { true }

# unbound method for bind
um = A.instance_method(:meth1)

# number of iterations
n = 12000 * 600

Benchmark.bm(22) do |x|

  x.report('instance_eval/str') do
    for i in 1..n; A.instance_eval(str); end
  end

  x.report('class_eval/str') do
    for i in 1..n; A.class_eval(str); end
  end

  x.report('eval/str') do
    for i in 1..n; eval(str, a_binding); end
  end

  x.report('define_method/class') do
    for i in 1..n; class A; define_method(:meth2, &$proc2); end; end
  end

  x.report('define_method/send') do
    for i in 1..n; A.send(:define_method, :meth2, &$proc2); end
  end

  x.report('def/unbind/bind') do
    for i in 1..n
      class A; def meth2; true; end; end
      A.instance_method(:meth2).bind(A.new)
    end
  end

  x.report('instance_eval/proc') do
    for i in 1..n; A.instance_eval(&proc1); end
  end

  x.report('class_eval/proc') do
    for i in 1..n; A.class_eval(&proc1); end
  end

  x.report('def') do
    for i in 1..n; class A; def meth2; true; end; end; end
  end

  x.report('method/bind') do
    for i in 1..n; um.bind(A.new); end
  end

end

Surprise 10min Benchmark: eval, class_eval, instance_eval, define_method, bind

Posted over 7 years back at Wood for the Trees

What is the fastest way to dynamically define a method? define_method? class_eval? instance_eval? With strings or procs? Maybe we can pull out some arcane magic and use instance_method and bind (depending on what we want to do).

We all need to use some kind of eval at some point and, while it will not usually effect performance when used sparingly, sometimes it just has to make a serious appearance. When I saw how slow RSpec is in comparison to the venerable Test::Unit, I discovered the way it handles its contexts: each one is individually instance_eval’d into an empty ContextEvalModule. It isn’t the only reason for being slower, but it is one and one which can really mount up on big projects.

So, moving on from RSpec, Test::Unit and my baseline, MicroTest (see previous post), I became perversely interested in benchmarking all the ways of doing it and found some surprises.

Results (Ruby 1.8.4)

                            user     system      total        real
eval/str              112.540000   0.060000 112.600000 (112.615607)
instance_eval/str      99.510000   0.040000  99.550000 ( 99.564661)
class_eval/str        112.750000   0.060000 112.810000 (112.824374)
instance_eval/proc     56.750000   0.040000  56.790000 ( 56.802483)
class_eval/proc        56.440000   0.020000  56.460000 ( 56.464818)
define_method/class   112.420000   0.060000 112.480000 (112.489430)
define_method/send    111.540000   0.050000 111.590000 (111.610502)
def/unbind/bind        73.750000   0.060000  73.810000 ( 73.875800)
def                    52.670000   0.030000  52.700000 ( 52.705886)
method/bind            13.520000   0.010000  13.530000 ( 13.523194)

Analysis

I put it roughly in the order which I originally expected, with the slowest at the top.

The first thing that stunned me was the speed of define_method. It’s as slow as a snail. It’s practically eval, despite using a proc. I’ve been using it in preference before, thinking it was faster than any of the evals (proc or string). Apparently not.

The second revelation was how proc-based evals are about 50% faster than a def/unbind/bind cycle, which only has def as the evaluating part. That any eval is close to def is simply surprising. The instance_eval variety is the one used by RSpec, so I guess they picked the best one already.

The third shock was how slow def is! Granted, this is a lot of iterations, but it should be quicker than that, surely?

So it seems pretty plain that method unbinding as a tuning technique is rubbish, despite not evaluating anything, whereas a proc-based instance_eval or simple def are the clear winners.

But wait… what about Ruby 1.8.5?

Seeing the decrepitude of define_method made me wonder about the latest release of Ruby. I downloaded it, compiled it, got it working and ran the same bench:

Results (Ruby 1.8.5)

                            user     system      total        real
instance_eval/str     109.620000   0.050000 109.670000 (109.685393)
class_eval/str        113.840000   0.060000 113.900000 (113.910749)
eval/str              114.520000   0.060000 114.580000 (114.596238)
define_method/class    70.220000   0.040000  70.260000 ( 70.264506)
define_method/send     68.030000   0.040000  68.070000 ( 68.066688)
def/unbind/bind        73.690000   0.030000  73.720000 ( 73.741549)
instance_eval/proc     59.050000   0.030000  59.080000 ( 59.084445)
class_eval/proc        59.530000   0.030000  59.560000 ( 59.566885)
def                    52.870000   0.030000  52.900000 ( 52.895184)
method/bind            12.470000   0.010000  12.480000 ( 12.484069)

Anaylsis

I guess they fixed the problem and more besides. define_method is now marginally faster than def/unbind/bind (which has not budged an inch). I think I’ll continue to take the performance hit on define_method with 1.8.4, knowing I’ll want to upgrade later in the future and not change techniques.

The old recommendations hold true

  • instance_eval with a proc for class, instance or singleton evaluation
  • instance_eval for changing proc bindings
  • define_method for converting procs into methods
  • def for everything else
  • eval when you really know you need it

Note: These findings are only for def meth; true; end and may vary in complex cases.

Benchmark Code

require 'benchmark'

class A; def meth1; true; end; end

# defining using eval/class/instance
str = "def meth2; true; end"
a_binding = A.send(:binding)

# proc for class/instance
proc1 = Proc.new { def meth2; true; end }

# proc for define_method
$proc2 = Proc.new { true }

# unbound method for bind
um = A.instance_method(:meth1)

# number of iterations
n = 12000 * 600

Benchmark.bm(22) do |x|

  x.report('instance_eval/str') do
    for i in 1..n; A.instance_eval(str); end
  end

  x.report('class_eval/str') do
    for i in 1..n; A.class_eval(str); end
  end

  x.report('eval/str') do
    for i in 1..n; eval(str, a_binding); end
  end

  x.report('define_method/class') do
    for i in 1..n; class A; define_method(:meth2, &$proc2); end; end
  end

  x.report('define_method/send') do
    for i in 1..n; A.send(:define_method, :meth2, &$proc2); end
  end

  x.report('def/unbind/bind') do
    for i in 1..n
      class A; def meth2; true; end; end
      A.instance_method(:meth2).bind(A.new)
    end
  end

  x.report('instance_eval/proc') do
    for i in 1..n; A.instance_eval(&proc1); end
  end

  x.report('class_eval/proc') do
    for i in 1..n; A.class_eval(&proc1); end
  end

  x.report('def') do
    for i in 1..n; class A; def meth2; true; end; end; end
  end

  x.report('method/bind') do
    for i in 1..n; um.bind(A.new); end
  end

end

Introducing: MicroTest

Posted over 7 years back at Wood for the Trees

Something I cooked up in an hour for bootstrap testing a testing framework.

If anyone actually wants me to maintain it, just give a shout and I’ll gemify it.



# A super-small testing suite.
# Just two ways to assert:
#   expect { (whatever must return true) }
#   do_not_expect { (whatever must return false) }
#
# A microtest looks like this:
#
#   class BinaryMicroTest < MicroTest
#     def should_exit_cleanly
#       expect do
#         `ruby #{myexec}`
#         $? == 0
#       end
#     end
#   end
#
class MicroTest

  class MicroFailure < StandardError; end

  class << self

    attr_accessor :passed, :failed, :executed, :expectations, :planned, :plan, :failures

    def run
      init
      execute
      report
    end

    def init
      self.passed, self.failed, self.executed, self.expectations = 0, 0, 0, 0
      self.planned, self.plan = harvest
      self.failures = []
    end

    def harvest
      plan = []
      ObjectSpace.each_object(Class) do |k|
        if k.respond_to?(:superclass) && k.superclass == MicroTest
          plan << [k, k.instance_methods.grep(/^should_/)]
        end
      end
      planned = plan.inject(0) { |c, ary| c += ary[1].size; c }
      [planned, plan]
    end

    def execute
      puts "Running #{self.planned} test(s)..."
      self.plan.each do |klass, tests|
        tests.each do |test|
          instance = klass.new
          r = catch_failures(klass, test) { instance.send(test) }
          if r
            self.passed += 1
            print "."
            STDOUT.flush
          else
            self.failed += 1
            print "F"
            STDOUT.flush
          end
          self.expectations += instance.expectation_count
          self.executed += 1
        end
      end
    end

    def catch_failures(klass, test)
      begin
        yield
        true
      rescue Exception => e
        self.failures << [klass, test, e]
        false
      end
    end

    def report
      puts "\n\n"
      puts "%d planned, %d executed, %d passed, %d failed.\n%d expectations found." %
        [self.planned, self.executed, self.passed, self.failed, self.expectations]
      unless self.failures.empty?
        puts "\nFAILURE REPORT\n"
        self.failures.each { |f| report_failure(f) }
      end
    end

    def report_failure(f)
      puts "Suite: #{f[0]}\nTest: #{f[1]}\nException: #{f[2].class}\nMessage: #{f[2].message}"
      puts ("\t" << f[2].backtrace.join("\n\t"))
    end

  end

  attr_accessor :expectation_count

  def initialize
    self.expectation_count = 0
  end

  def expect(&block)
    self.expectation_count += 1
    raise MicroFailure, "should be true" unless block.call
  end

  def do_not_expect(&block)
    self.expectation_count += 1
    raise MicroFailure, "should be false" if block.call
  end

end

at_exit do
  MicroTest.run
end

Just dump that in a helper file and require it, as per normal Test::Unit practices.

Introducing: MicroTest

Posted over 7 years back at Wood for the Trees

Something I cooked up in an hour for bootstrap testing a testing framework.

If anyone actually wants me to maintain it, just give a shout and I’ll gemify it.



# A super-small testing suite.
# Just two ways to assert:
#   expect { (whatever must return true) }
#   do_not_expect { (whatever must return false) }
#
# A microtest looks like this:
#
#   class BinaryMicroTest < MicroTest
#     def should_exit_cleanly
#       expect do
#         `ruby #{myexec}`
#         $? == 0
#       end
#     end
#   end
#
class MicroTest

  class MicroFailure < StandardError; end

  class << self

    attr_accessor :passed, :failed, :executed, :expectations, :planned, :plan, :failures

    def run
      init
      execute
      report
    end

    def init
      self.passed, self.failed, self.executed, self.expectations = 0, 0, 0, 0
      self.planned, self.plan = harvest
      self.failures = []
    end

    def harvest
      plan = []
      ObjectSpace.each_object(Class) do |k|
        if k.respond_to?(:superclass) && k.superclass == MicroTest
          plan << [k, k.instance_methods.grep(/^should_/)]
        end
      end
      planned = plan.inject(0) { |c, ary| c += ary[1].size; c }
      [planned, plan]
    end

    def execute
      puts "Running #{self.planned} test(s)..."
      self.plan.each do |klass, tests|
        tests.each do |test|
          instance = klass.new
          r = catch_failures(klass, test) { instance.send(test) }
          if r
            self.passed += 1
            print "."
            STDOUT.flush
          else
            self.failed += 1
            print "F"
            STDOUT.flush
          end
          self.expectations += instance.expectation_count
          self.executed += 1
        end
      end
    end

    def catch_failures(klass, test)
      begin
        yield
        true
      rescue Exception => e
        self.failures << [klass, test, e]
        false
      end
    end

    def report
      puts "\n\n"
      puts "%d planned, %d executed, %d passed, %d failed.\n%d expectations found." %
        [self.planned, self.executed, self.passed, self.failed, self.expectations]
      unless self.failures.empty?
        puts "\nFAILURE REPORT\n"
        self.failures.each { |f| report_failure(f) }
      end
    end

    def report_failure(f)
      puts "Suite: #{f[0]}\nTest: #{f[1]}\nException: #{f[2].class}\nMessage: #{f[2].message}"
      puts ("\t" << f[2].backtrace.join("\n\t"))
    end

  end

  attr_accessor :expectation_count

  def initialize
    self.expectation_count = 0
  end

  def expect(&block)
    self.expectation_count += 1
    raise MicroFailure, "should be true" unless block.call
  end

  def do_not_expect(&block)
    self.expectation_count += 1
    raise MicroFailure, "should be false" if block.call
  end

end

at_exit do
  MicroTest.run
end

Just dump that in a helper file and require it, as per normal Test::Unit practices.

Hobo development site

Posted over 7 years back at The Hobo Blog

It’s really tremendous news that we’re starting to get a bit of a community feel going. We’ve had a fix for sqlite, a little rakefile contributed to handle rdoc, plus some syntax fixes for that. We’ve had the first proper code contribution from simondo. And we’ve even had our first discussion thread where the question answerer was not me :-) Not to mention a ton of ideas and suggestions. A very big thank-you indeed to you all!

Not to mention more than 5,000 visitors to the site in this first week of January.

So to kick-off the community involvement, I’ve put the development site together at dev.hobocentral.net.

I’ve got a text-file where I’ve been keeping notes of things that need fixing / extending, and questions that need answering, and I’ve started posting tickets for these. I’ve just done the first 17. I think there’ll be about 50 all together, and that’s just for starters of course.

I’m using trac so there’s a wiki too, although I dislike the wiki-markup. I’m trying to figure out how to get it to use Markdown – if anyone can help with that I’d much appreciate it.

Hobo development site

Posted over 7 years back at The Hobo Blog

It’s really tremendous news that we’re starting to get a bit of a community feel going. We’ve had a fix for sqlite, a little rakefile contributed to handle rdoc, plus some syntax fixes for that. We’ve had the first proper code contribution from simondo. And we’ve even had our first discussion thread where the question answerer was not me :-) Not to mention a ton of ideas and suggestions. A very big thank-you indeed to you all!

Not to mention more than 5,000 visitors to the site in this first week of January.

So to kick-off the community involvement, I’ve put the development site together at dev.hobocentral.net.

I’ve got a text-file where I’ve been keeping notes of things that need fixing / extending, and questions that need answering, and I’ve started posting tickets for these. I’ve just done the first 17. I think there’ll be about 50 all together, and that’s just for starters of course.

I’m using trac so there’s a wiki too, although I dislike the wiki-markup. I’m trying to figure out how to get it to use Markdown – if anyone can help with that I’d much appreciate it.

Send me your favorite vi Commands and Stories

Posted over 7 years back at schadenfreude

Vi has been around for over 30 years now and in celebration of that we are compiling a list of obscure vi/vim commands and anecdotes.

Send your submission to viroundup@gmail.com or comment in this article. Include a useful vi/vim command and or anecdote about how vi saved the day. After two weeks I will be compiling a large article of your submissions so be sure to include your name and or homepage so I may cite you.

Move to Mephisto

Posted over 7 years back at Cody Fauser

I finally bit the bullet and moved my blog over to Mephisto. So far I am loving it. Thanks to Justin Palmer and Rick Olson for all of their hard work that went into making this an awesome application.

I migrated from Typo and used the great howto Converting Typo to Mephisto on the Octoblog. What an awesome name for a blog! The only thing I did differently, since I'm using the latest code from the Mephisto trunk, was the support for Typo style article URLs. I just opened up config/routes.rb and tweaked it to look as follows:

1
2
3
4
5
6

ActionController::Routing::Routes.draw do |map|
  Mephisto::Routing.connect_with map do
    map.connect 'articles/*path', :controller => 'mephisto', :action => 'dispatch'
  end
end

JRuby w/ Full Rails Support in February... Of 2007?

Posted over 7 years back at Ryan Tomayko's Writings

Charles Nutter:

… Now this might change, but we’re really hoping to claim full Rails support some time in February. We’re not sure if that will mean 90% of 1.1.6 test cases or 100% of 1.2 test cases, but we’re weighing options now…

Wha? I haven’t been following the project as closely as I'd like but for some reason I was thinking this was 6-9 months off.

While we’re projecting, does anyone know where I can monitor the status of a released J2SE under the GPL?

How about someone throws out a rough guess for when we’ll see Rails running on a GPL'd JVM? March? July? 2009? Anyone?

Stupid JavaScript Hacks

Posted over 7 years back at zerosum dirt(nap) - Home

I’m usually not prone to MLP (mindless link propagation) but sometimes I just can’t help it. Case in point: this cool l’il bit of JavaScript. Good for a quick chuckle.

Copenhagen Ruby Brigade - Ruby on Rails Podcast

Posted over 7 years back at Ruby on Rails Podcast

Obie Fernandez interviews the members of the Copenhagen Ruby Brigade in Denmark.

Putting Hobo through its paces

Posted over 7 years back at The Hobo Blog

To many balls in the air at once, that’s my problem. There’s Hobo the open source project – keeping updates flowing, responding to problems you folks are hitting, documentation, and on and on and on. Then there’s paying the rent, and right now that means working on a least two, maybe three or four commercial web-sites. The good news is that all of these projects are being built using Hobo, so I’m getting to put Hobo through its paces and I’m really enjoying what I’m seeing.

Yesterday, for example, I was working on one app and noticed that a particular class of user was able to edit something that should have been read-only. I made a quick change to the updateable_by? method on the model in question, and refreshed the browser. All the in-place-editors changed to read-only text. On every page in the site. I made a similar change to deleteable_by?, and a whole bunch of “Remove” buttons vanished. Unless I logged in as an administrator – then they all came back again.

In another story, I was editing a view of a person. People in this app have many discussions. There is a preview of some recent discussions on the person’s home page, but I realised I needed a place where they could see all of their ongoing discussions. I added a quick <object_link attr="discussions"/> and then, er, refreshed the browser. Job done - the page in question was built entirely automatically by Hobo. OK to be honest I’ll probably have to customise that page a little, but that will be a quick and painless task.

All in all it’s kind of a jaw-dropping experience. Right now things are still at the stage where I frequently find myself dipping into the Hobo source to add a small feature or to tweak something to be a bit more flexible, or implement some corner case. But the need to do that is diminishing rapidly. Once Hobo really matures, I really think it’s going to set a new bar for how much work it takes to build a web app.

The app I’ve talked about is a fairly sophisticated group collaboration application, with discussions, events and calendaring, classified adverts and a bunch of other stuff. At some point I’ll host it for the public as a demo of the capabilities of Hobo. For one thing that should help dispel the misconception I’ve seen in some places that Hobo is only for building prototypes. Hobo is for that, and for real applications too.

Putting Hobo through its paces

Posted over 7 years back at The Hobo Blog

To many balls in the air at once, that’s my problem. There’s Hobo the open source project – keeping updates flowing, responding to problems you folks are hitting, documentation, and on and on and on. Then there’s paying the rent, and right now that means working on a least two, maybe three or four commercial web-sites. The good news is that all of these projects are being built using Hobo, so I’m getting to put Hobo through its paces and I’m really enjoying what I’m seeing.

Yesterday, for example, I was working on one app and noticed that a particular class of user was able to edit something that should have been read-only. I made a quick change to the updateable_by? method on the model in question, and refreshed the browser. All the in-place-editors changed to read-only text. On every page in the site. I made a similar change to deleteable_by?, and a whole bunch of “Remove” buttons vanished. Unless I logged in as an administrator – then they all came back again.

In another story, I was editing a view of a person. People in this app have many discussions. There is a preview of some recent discussions on the person’s home page, but I realised I needed a place where they could see all of their ongoing discussions. I added a quick <object_link attr="discussions"/> and then, er, refreshed the browser. Job done - the page in question was built entirely automatically by Hobo. OK to be honest I’ll probably have to customise that page a little, but that will be a quick and painless task.

All in all it’s kind of a jaw-dropping experience. Right now things are still at the stage where I frequently find myself dipping into the Hobo source to add a small feature or to tweak something to be a bit more flexible, or implement some corner case. But the need to do that is diminishing rapidly. Once Hobo really matures, I really think it’s going to set a new bar for how much work it takes to build a web app.

The app I’ve talked about is a fairly sophisticated group collaboration application, with discussions, events and calendaring, classified adverts and a bunch of other stuff. At some point I’ll host it for the public as a demo of the capabilities of Hobo. For one thing that should help dispel the misconception I’ve seen in some places that Hobo is only for building prototypes. Hobo is for that, and for real applications too.

New Years Resolutions

Posted over 7 years back at zerosum dirt(nap) - Home

Back from my requisite holiday visitations and feeling refreshed. Now it’s time to get back to work. Here’s some tentative goals for the new year:

  • Get up earlier in the morning. Start work earlier in the morning. Finish work earlier in the evening.
  • Focus more on Ruby this year, less on Java. Delete PHP from resume.
  • Get a gym membership and actually go on a regular basis.
  • Take a break from client (ie paid) work for a change and get one of my own ideas off the ground before summer.
  • Print some damn business cards. Stop coming up with cute excuses about why they’re lame and learn to conform. Just a little.
  • Go to at least one conference. Go to at least one UG semi-regularly.
  • Bathe the dog more often. He is a stank factory.

Getting Data from MySQL into Excel

Posted over 7 years back at schadenfreude

The other title of this article could be Outputting data from MySQL into a Comma Separated Value file (.csv)

Short and sweet, this article is more for me to store this SQL syntax in an easily recoverable place as I seem to forget how to use it every time I need to output something into CSV format from MySQL.