Thoughts and tutorials on programming
Thursday, December 03, 2009
beyond clearplay
Wednesday, September 23, 2009
Pictures wrong sometimes?
Anybody else notice that pictures are sometimes...just wrong?
ping!
Benefits of Firefox
The benefits of firefox:
the adblock plus plugin [plus myriad other plugins]
Reasonably speedy, well supported.
Drawbacks:
It takes up more RAM than Chrome (i.e. slower for older machines), renders, for me, slightly slower than Safari/Chrome [in windows, at least].
Written only to be able to say I was the first to sidewiki FF :)
Beautiful
Google Earth is a beautiful thing--the stand alone app is smoother than the google maps web version.
[written just to be able to say I wrote the first sidewiki for google earth]
Wednesday, August 05, 2009
how to compile ruby with increased garbage size
Monday, August 03, 2009
how to proxy to a port when your firewall blocks that port [using mod_proxy instead]
For me, it was getting some external server to forward all requests on to that port.
I realize you can use ssh -Rport:host:port as well (through some other server), however ssh tunnelling was at times interrupted and didn't have a retry or restart, it seemed, at least that I knew of.
Anyway the final forward was:
1) create new subdomain that will forward it on.
2) edit apache's conf [apache.conf in my example] to forward things on
Order deny,allow
Allow from all
ServerName audio-mp3.ibiblio.org.8000.doachristianturndaily.info
ProxyPass / http://audio-mp3.ibiblio.org:8000/
3) install forwarders:
sudo a2enmod proxy
sudo a2enmod proxy_http
4) restart apache
5) enjoy the tunes [in my case].
Saturday, August 01, 2009
how to setup a remote git repository using ssh
$ ssh myserver.com
Welcome to myserver.com!
$ mkdir /var/git/myapp.git && cd /var/git/myapp.git
$ git --bare init
Initialized empty Git repository in /var/git/myapp.git
$ exit
Bye!
Add the remote repository to your existing local git repo and push:
$ cd ~/Sites
$ mkdir myapp
$ git init
$ git remote add origin ssh://myserver.com/var/git/myapp.git
$ touch README
$ git add README
$ git commit -m "initial commit"
$ git push origin master
Thursday, July 23, 2009
How to compile using visual studio for ruby
========================
The most obvious criticism of this plan is that it will lead to mixing of microsoft runtime c libraries. From my experience this works as long as extension developers follow the rules described here:
http://msdn.microsoft.com/en-
To be more concrete, this boils down to two simple rules:
* If you call ALLOC or ALLOC_N, use xfree and not free
* Don't call sprintf or printf in an extension, instead use rb_f_sprintf/rb_vsprintf/rb_
If an extension violate these two rules then its obvious, a segmentation fault happens. Thus these bugs are easy to find and easy to fix.
Since VC6 is thankfully no longer available, supporting msvc absolutely, positively requires mixing c runtime libraries and therefore extension writers must follow these two simple rules.
Tuesday, June 23, 2009
rdocs for all gems from rubyforge
Why?
Because it's convenient to have all rdocs installed in a single known place to be able to browse/search them. Because it's a central repository, too, it eliminates the need to install local rdocs for gems, which (when you turn it off) means you install local gems *much* more quickly. It makes me happy every time I do a "gem install" :)
It also eliminates the need for running a local gem server.
These gems' rdocs are all in the hanna theme, which provides for method search and an easy on the eyes layout. Though darkfish is also quite pretty, it isn't as easy to read because of font contrast.
Check it out!
http://allgems.faithpromotingstories.org/gems
core docs: http://coredocs.faithpromotingstories.org/
Feedback welcome.
Note also that they're using a temporarily subdomain url. If anybody is interested and could help me with a subdomain of a more ruby related url that would be cool. I hate to fork over that $10 a year for another domain you know me :)
Enjoy.
=r
Thursday, June 18, 2009
How to save MUCH RAM when running rails (linode/slicehost) and mod_rails passenger
1: Install a 32-bit OS
Ruby uses twice as much RAM if you're in 64-bit than in 32-bit [and most other things do, too]. Use 32-bit! [linode has options to do this easily].
PassengerMaxInstancesPerApp 1
total mem, RSS, ... name
117m 49m 3156 S 0 13.8 0:00.93 ruby # spawner 49M
171m 89m 2240 S 0 24.7 0:00.61 ruby # instance 89m
fix:
use
this results in [slower startup times and]
RAM, RSS...process nameSavings: (assuming you only want one process per rails app): 49m (on 64-bit).
143m 72m 3480 S 0 20.1 0:01.69 ruby
Enjoy!
Other potential tricks:
use nginx instead of apache--faster, much better RAM usage. Potential savings:
refs:
http://groups.google.com/group/phusion-passenger/browse_thread/thread/df1fc1073dbef38
[1] http://www.ruby-forum.com/topic/170608#new
[2] http://blog.evanweaver.com/articles/2009/04/09/ruby-gc-tuning/
[3] http://articles.slicehost.com/2007/9/11/ubuntu-feisty-mysql-and-ror
Thursday, June 04, 2009
state of the art in ruby compilation/JIT
Ex: yarv compiles ruby code to yarv internal byte code. But there are other levels, which we hope to exploit in order to make a faster ruby. We'll discuss some different style of compilation (JIT and otherwise).
There are a few existent libraries that do translation.
ruby2c: translates code like
def fact(n)
n*(fact(n-1))
end
fact(1000) # it needs this as a hint to know what type the fact method takes
to standard C (at least in all examples I've seen)
int fact(int n) {
return(n*fact(n-1));
}
So their ansiC aspect is the most hard-core "I don't want this to lany of this in Ruby at all after it's done."
pros: fast as can be. cons: see below.
rubyinline, interestingly, wraps something like
"int fact(int n) {
return(n*fact(n-1));
}"
with converters to call and return to and from Ruby, so you can call fact(1000) in your ruby code and it will work.
One interesting idea would be to pipe the output of ruby2c to rubyinline. Alas, ruby2c seems somewhat broken currently.
cons: you have to write in C. That is not what most of us want to ever have to do again.
I think where this perspectives fall apart is that they're not as flexible/dynamic as normal Ruby. It might have trouble with:
a = [/abc/, 'abc', 33]
b = 33
a.each{|thing| puts thing.inspect; b+= 1} # dynamic arrays probably not well handled, as well as ruby internal methods like 'inspect', blocks, etc.
or
a = [/abc/, /def/]
a.each{|reg| if "abc" =~ reg then puts 'yes'; end} # regex probably isn't supported, a lot of the rest of the stdlib
Then again, I haven't tried it since ruby2c doesn't even work for me.
pros: as fast as fast can be. also comes with a dependency walker so that it can "surmise" which classes of methods you'll be passing in, then it programs for just those.
cons: doesn't handle all ruby (AFAIK).
Maybe in its current state they're useful for doing mathematically intense operations? Dunno. Rubyinline is a little more useful, but requires writing in C.
Ruby2Cext takes a "ruby to ruby C" approach. Its original aim was to produce ruby compatible code equivalents in C.
i.e. the ruby:
def go
3
end
translates to
VALUE go_c(VALUE self) {
return INT2NUM(3); // uses all ruby types
}
void init_File {
rb_method_register(someClass, "go", go_c, 0);
}
It also translates blocks and everything to its ruby c equivalents (using ruby c syntax) . For 1.8 that was said to yield a 2X speed increase.
They also added some plugins, one gives you the ability to "freeze" certain C method calls, i.e.
if it encounters String#strip it always calls straight to the C function for String#strip [thus avoids doing a ruby method call]
ex:
def go
"".strip
end
Generates code that looks up String#strip and "saves off" the function's exact location [who would want to override String#strip, right?].
Thus the above ruby is converted roughtly to something like:
void *string_strip_function = Qundef;
VALUE go_c(VALUE self) {
VALUE str = rb_str_new("");
return strip(str);
}
VALUE strip(VALUE fromThis) {
switch(GET_TYPE(fromThis)) {
case STRING :
return *(string_strip_function)(fromThis);// this avoids rb_funcall to lookup then call strip
else:
return rb_funcall3(rb_intern("strip"), fromThis);
}
}
void init_File {
rb_method_register(someClass, "go", go_c, 0);
strip_function = lookup_internal_ruby_c_method(rbString, "strip");
}
So you can see this avoids a few rb_funcalls to built-in methods, and is still almost entirely ruby compatible. This results in "up to 5x speedup" or so it says.
drawbacks to rb2cext: 1.9 compiles ruby to bytecode--perhaps rb2xext won't have as much a gain if used with a 1.9 VM, since it already does some of this work, though profiling would help evaluate this.
All the above examples were static compilers. Run once before runtime [or at eval time].
Another class would be JIT dynamic compilers. Jruby is really the only one that has anything like that currently, and yet somehow it doesn't yet seem to be quite as fast as 1.9 without a JIT [1][4].
There exists a "demo" JIT using ruby2c, as well [2]. It optimizes a single method, but at least shows you how you could do something more dynamic.
So where can/should the future of ruby interpreters lie? There's lots of things you could try.
A few are making it tighter in C, or making it more JIT'y, or making it moree "dependency walking" so it can pre-optimize the paths that are guaranteed to only have a certain class passed in to them.
re: making it tighter in C
One drawback currently to ruby2cext is that if you define
class A
def this_method
calls_this_other_method
end
def calls_this_other_method
end
end
it will translate this (loosely) as
VALUE calls_this_other_method = rb_intern("calls_this_other_method"); // cache the symbol away
VALUE this_method_c(VALUE this) {
check_right_parameters();
return rb_funcall(calls_this_other_method);
end
VALUE calls_this_c(VALUE this) {
check_right_parameters();
return Qnil;
}
Note that it did not optimize the call between this_method and calls_this_other_method, but required ruby do rb_funcall. This is the perfectly valid ruby way--you can override calls_this_other_method later and it will work with the new method, but in most cases after a warm up phase methods aren't overridden, so the rb_funcall could be avoided by calling the method directly. So we could hard code the calls to the other known ruby (now C) methods.
If we were to assume that class method definitions were "frozen" after a specific setup phase, then a few more optimizations would be available, the above being one of them. [3]
In other words, rb2cext could become more C-y, with direct calls from method to method.
Interestingly, ruby2c also has a RubytoRubyC component (I never saw any examples of it posted, and couldn't get it to run) which might attempt something similar.
At the same time, ruby2c could become more ruby-y, i.e. integrating with the stdlib [i.e. if you know a string is being passed in, and the command is
def go a
a << '3'
end
then you could call rb_str_concat directly.
So there are two ways of action: one to make ruby to c translators more c-y, one to make them more ruby-y. Static compile time type analysis might make it so you can guarantee an object's class and optimize for it. That's an option.
Another option would be to create something more JIT'y. Profile to discover the "hot paths", then write C that optimizes for the common path (then you could make direct C calls outside your current class, too).
So what to do? Thoughts?
-=r
[1] http://blog.pluron.com/2009/05/ruby-19-performance.html
[2] http://github.com/seattlerb/zenhacks/tree/master
[3] For instance you could c-ify every ruby method in existence, with direct calls to any C methods within the same class (since we assume they all exist now). Ludicrous allows for this: http://betterlogic.com/roger/?p=1534 though I haven't experimented speed-wise.
[4] http://groups.google.com/group/ruby-benchmark-suite/browse_thread/thread/f56b4335cfd3ec57/c7babfb676d71450?lnk=gst&q=patch+gc#c7babfb676d71450 shows how 1.9 with a GC patch can be competitive to jruby.
Saturday, May 30, 2009
how to install sqlite3 from source on ruby mingw (1.8 or 1.9)
3.5) install msysgit, then git clone git://github.com/luislavena/sqlite3-ruby.git, then cd into it.
mingw ruby 1.9/1.8 how to install mysql from source
Looks like the only way I know of is (assuming ruby 1.9 with devkit [2])
1) download mysql 5.0.x windows "without installer"
2) unzip, put/rename it to c:\mysql
3) download mysql 2.8.1 binary from tmtm http://www.tmtm.org/en/mysql/ruby/
4) edit extconf so that anywhere it says mswin32 it now says mswin32|mingw
4a) make sure that mysql's bin are *not* in your path [might not be ncessary, but just in case]
5) run ruby extconf.rb -- --with-mysql-include=c:/mysql/include --with-mysql-lib=c:/mysql/lib/opt
6) run make, then run make install
7) make sure libmysql.dll is in your path or in current directory 8) run ruby -e 'require "mysql"' -- should work.
[1] http://www.ruby-forum.com/topic/188199#new
[2] http://programming-gone-awry.blogspot.com/2009/05/ruby-19-one-click-installer.html
Wednesday, May 27, 2009
how to setup a complete mingw msys build environment for ruby (including dependencies)
Here's how: use Luis Lavena's pre built scripts to set it up for you (in this case to set it up for building a complete version of ruby), then tie in to the msys and mgit that it created for you.
steps:
download rubyinstaller's source, git clone git://github.com/oneclick/rubyinstaller.git
then build a version, "any version" of ruby with it, a la
cd rubyinstaller
rake # wait about 30 minutes :)
now set your path to "use" its newly downloaded, loaded with dependencies, versions of mingw and msys, a la build_env.bat contents (in my case):
set PATH=D:\dev\downloads\rubyinstaller\sandbox\mingw\bin;D:\dev\downloads\rubyinstaller\sandbox\msys\bin;D:\dev\downloads\rubyinstaller\sandbox\msys\usr\local\bin;%PATH%
Monday, May 18, 2009
e text editor on virtualbox howto
e text editor on andlinux howto
finally got the e text editor to work on andlinux! sweet!
how to:
1) install andLinux, choose coFS so you can see *all* your windows files.
2) resize the default partition to > 2GB default [1]
http://ext2resize.sourceforge.net/download.html
extract c:\program files\andlinux\toporesize.zip
shutdown andlinux
now run (for 10GB)
C:\Program Files\andLinux\ImageResizeTool\toporesize-0.7.1>tfile ..\..\Drives\base.vdi 10000
now restart andlinux
and within it:
sudo apt-get install build-essential -y # install gcc
install ext2resize, then run
sudo ext2online /dev/cobd0
3) "give yourself more swap ram" [at least 1GB for sure 2GB swap file works well] [2]
root@andLinux:~# swapoff /dev/cobd1 |
c:\Program Files\andLinux\Drives>type swap.vdi >>swap.vdi2 |
several times
or in ruby:
a = File.new 'swap.vdi2', 'w'
a.seek 2e9
a.write 'a'
4) checkout the git repository
sudo apt-get install git-core
git clone git://github.com/etexteditor/e.git
apply this patch:
http://e-texteditor.com/forum/viewtopic.php?p=13046#13046
install some unlisted dependencies
sudo apt-get install build-essential curl libgtk2.0-dev
then follow the directions within linux-notes.txt
Then follow the directions under the section "it all comes crashing down"
http://fixnum.org/blog/2009/e_on_fedora
And you *might* have a working andlinux e text editor.
[1] http://www.andlinux.org/forum/viewtopic.php?p=1581#1581
[2] http://www.andlinux.org/forum/viewtopic.php?p=956&sid=ebe8efafb867fe03519fcf166dbe104e
Friday, May 08, 2009
ruby 1.9 one click installer
Here's how to get a pretty easy working 1.9/1.8.6 mingw (from my post to ruby installers list)
for the files at
http://rubyinstaller.org/downloads/
quick install instructions (1.8.6, 1.9):
install a ruby one click installer to c:\Ruby
afterward,
c:\Ruby now has
bin\
lib\
share\
Now unzip the devkit.7z and move its contents into the same folder
(devkit is a bundled up mingw GCC+msys).
i.e.
c:\Ruby now has
bin\
lib\
share\
devkit\
INSTALL.txt
(note: the message "This folder already contains a folder named bin"
is expected--choose "yes" to confirm folder replace).
next add c:\Ruby\bin to the beginning of your path and enjoy the power
of a faster ruby with a compiler.
==More Detailed instructions==
Same as above--however, if you want to use a folder other than c:\Ruby
then please change devkit/msys/1.0.11/etc/fstab to properly point to
the right directories for mingw and /usr/local
How to add ruby\bin to your path:
either do this on the command line thus:
set PATH=c:\ruby-1.9.1-p0-i386-mingw32\bin;%PATH%
or change the PATH variable within my computer -> properties ->
advanced -> environment variables (add it to the front of path within
"system variables").
== How to determine success ==
If successful you should get an output like (for 1.8):
C:\>ruby -v
ruby 1.8.6 (2009-03-31 patchlevel 368) [i386-mingw32]
C:\>gcc -v
Reading specs from C:/Ruby/devkit/gcc/3.4.5/bin/../lib/gcc/mingw32/3.4.5/specs
...
and installing binary gems should work properly:
C:\>gem install json
Building native extensions. This could take a while...
Successfully installed json
...
If a gem fails to compile (ex: because of lack of headers), you can at
times get away with doing a
gem install gemname --platform=mswin32
this installs the msvc binaries for it. They are *typically* compatible. It's safer, however, to download the headers and compile it locally, and submit your process upstream so they can release a quality mingw binary :)
Enjoy!