What use can I give to Ruby threads, if they are not really parallel?
When I first discovered threads, I tried checking that they actually worked as expected by calling sleep in many threads, versus calling sleep normally. It worked, and I was very happy.

But then a friend of mine told me that these threads weren't really parallel, and that sleep must be faking it.

So now I wrote this test to do some real processing:

    class Test
      ITERATIONS = 1000
      
      def run_threads
        start = Time.now
        
        t1 = Thread.new do
          do_iterations
        end
        
        t2 = Thread.new do
          do_iterations
        end
        
        t3 = Thread.new do
          do_iterations
        end
        
        t4 = Thread.new do
          do_iterations
        end
        
        t1.join
        t2.join
        t3.join
        t4.join
        
        puts Time.now - start
      end
      
      def run_normal
        start = Time.now
    
        do_iterations
        do_iterations
        do_iterations
        do_iterations
          
        puts Time.now - start
      end
      
      def do_iterations
        1.upto ITERATIONS do |i|
          999.downto(1).inject(:*) # 999!
        end
      end
    end

And now I'm very sad, because run_threads() not only didn't perform better than run_normal, it was even slower!

Then why should I complicate my application with threads, if they aren't really parallel?
What use can I give to Ruby threads, if they are not really parallel?
===

When I first discovered threads, I tried checking that they actually worked as expected by calling sleep in many threads, versus calling sleep normally. It worked, and I was very happy.

But then a friend of mine told me that these threads weren't really parallel, and that sleep must be faking it.

So now I wrote this test to do some real processing:

    class Test
      ITERATIONS = 1000
      
      def run_threads
        start = Time.now
        
        t1 = Thread.new do
          do_iterations
        end
        
        t2 = Thread.new do
          do_iterations
        end
        
        t3 = Thread.new do
          do_iterations
        end
        
        t4 = Thread.new do
          do_iterations
        end
        
        t1.join
        t2.join
        t3.join
        t4.join
        
        puts Time.now - start
      end
      
      def run_normal
        start = Time.now
    
        do_iterations
        do_iterations
        do_iterations
        do_iterations
          
        puts Time.now - start
      end
      
      def do_iterations
        1.upto ITERATIONS do |i|
          999.downto(1).inject(:*) # 999!
        end
      end
    end

And now I'm very sad, because run_threads() not only didn't perform better than run_normal, it was even slower!

Then why should I complicate my application with threads, if they aren't really parallel?