2007년 12월 20일 목요일

Seo? What Seo?

My name is Seo Sanghyeon. Apparently, SEO also stands for Search Engine Optimization. That seems to be an enough reason for "SEO professionals" to spam my blog. Too bad.

2007년 9월 26일 수요일

IronPython/Mono benchmarks

There have been significant improvements in the performance of Mono runtime this year. Three Mono releases were made:

2007-02-07 Mono 1.2.3
2007-05-15 Mono 1.2.4
2007-08-30 Mono 1.2.5

I adapted some benchmarks from "shootout" benchmarks, namely cheap-concurrency, nsieve, recursive, and ran it with IronPython 1.1 using Mono 1.2.3, 1.2.4, 1.2.5, and current SVN version. Here is a result:



Great work!

By the way, the plot was done with Matplotlib. Highly recommended.

All code to run the benchmark is available from FePy SVN:
https://fepy.svn.sourceforge.net/svnroot/fepy/bench/

And so is the raw data:
http://sparcs.kaist.ac.kr/~tinuviel/download/IronPython/bench/

2007년 7월 26일 목요일

Teaching IronRuby math tricks

The first release of IronRuby brought a lot of buzz, and in my opinion rightly so. However, if you expect it to run Rails, seemlessly integrating ASP.NET widgets today, I must say you're delusional. Have you tried to run it at all? People, there are reasons why it is versioned Pre Alpha.

In the post titled "Is IronRuby mathematically challenged?", Antonio Cangiano rightfully complains of these fads. He writes:

Well, I was very interested in trying out IronRuby, but I immediately discovered that it is very crippled from a mathematical standpoint, even for a pre-alpha version. (...) However after running some simple tests, it is clear that a lot of work is required in order for this project to live up to the buzz that is being generated online about it, when you take into account that even some simple arithmetic functionalities are either flawed or missing altogether.


To be fair, the focus of this release is working method dispatch core and built-in class Array and String, as John Lam himself wrote. But it is understandable for people to worry that these problems may be difficult to remedy. Fortunately, it is not the case, as I will demonstrate below.

Remember, IronRuby is open source, so you can fix problems yourself. Can't divide two floating numbers? It turns out to be as easy as adding one-line method to FloatOps class. Big numbers don't work? Conviniently, DLR provides a high performance class to deal with arbitrary precision arithmetic, namely Microsoft.Scripting.Math.BigInteger. This is how Python long type is implemented in IronPython.

Without further ado, here's a small patch (34 lines added, 1 lines deleted) to remedy problems Antonio pointed out. I think you will be able to understand it even if you don't know C#! It's that simple.

http://sparcs.kaist.ac.kr/~tinuviel/download/IronRuby/pre-a1/patch-math

If you are using a certain operating system which lacks such a basic tool like patch, I heartily recommend you to head to GnuWin32 and get it. Add it to your PATH. Let's assume that you extracted the zip file to C:\. You need to pass --binary option to patch because of different line endings; I generated the patch on Linux.

C:\IronRuby-Pre-Alpha1>patch --binary -p1 < patch-math
patching file Src/Ruby/Builtins/Bignum.cs
patching file Src/Ruby/Builtins/FixnumOps.cs
patching file Src/Ruby/Builtins/FloatOps.cs

After that, you need to build ClassInitGenerator. This is necessary because the patch adds new methods to built-in classes.

C:\IronRuby-Pre-Alpha1>cd Utils\ClassInitGenerator
C:\IronRuby-Pre-Alpha1\Utils\ClassInitGenerator>msbuild

Now it is built, you need to run it to regenerate Initializer.Generated.cs. There is a batch file to do this, GenerateInitializers.cmd, but for some inexplicable reasons it won't work because it got the parent directories(..) one too many. It seems that they haven't tested this.

C:\IronRuby-Pre-Alpha1\Utils\ClassInitGenerator>cd ..\..
C:\IronRuby-Pre-Alpha1>Bin\Debug\ClassInitGenerator > Src\Ruby\Builtins\Initializer.Generated.cs

Now to the main build.

C:\IronRuby-Pre-Alpha1>msbuild

Let's test! Did IronRuby learn the math we taught?

C:\IronRuby-Pre-Alpha1>cd Bin\Debug
C:\IronRuby-Pre-Alpha1\Bin\Debug>rbx

IronRuby Pre-Alpha (1.0.0.0) on .NET 2.0.50727.832
Copyright (c) Microsoft Corporation. All rights reserved.
>>> 1/3.0
=> 0.333333333333333
>>> 1.0/3.0
=> 0.333333333333333
>>> 2**3
=> 8
>>> 1_000_000 * 1_000_000
=> 1000000000000
>>> exit

It did!

2007년 6월 11일 월요일

pyprof progresses

It has been a week since the beginning of pyprof. The project is progressing well.

The code is in the usual place:
https://fepy.svn.sourceforge.net/svnroot/fepy/trunk/pyprof/

There are some Makefile updates. Some variables are now defined at the top of the file. You may want to change the path to Mono, Python, and IronPython there.

I wrote a call tracer in pure Python using sys.setprofile which should print the essentially same output as pyprof. The filename is prof.py, and you can type "make testpy" to see its output. Compare the output with one from "make test".

You can type "make test.out" to update the reference output. This file is quite long, as I swapped the sample script to one using nntplib from the Python standard library. The script connects to Gmane and print the description of comp.lang.python newsgroup.

Some new features of the call tracer includes obvious ones like printing method leave events, and indenting messages to show the call depth. After some refactoring, logic for filtering non-Python assemblies and IronPython-internal methods now live in the separate function. I plan to split them to the separate file actually.

IronPython-internal TryGetExtraValue calls are now ignored. This was obvious once I moved to profiling real programs.

In the last post, I wrote that test output assumes you have blank site.py. Then I remembered that Python has a command line option -S to disable importing of site.py. Unfortunately, this revealed a bug in IronPython. I reported the bug to the IronPython mailing list and wrote a patch to fix it.

Development of pyprof also revealed a bug in the Mono runtime. When the method is left by throwing an exception, the profiler was not notified about the event. This is problematic, because the Python Library Reference specifies about sys.setprofile (link) that "the return event is reported even when an exception has been set".

I reported the bug to the Mono mailing list and subsequently wrote a 4-line patch. That patch actually took 4 hours to come with (a line per an hour :-), but I learned a lot in the process. Miguel de Icaza promptly applied the patch for me.

Now I need to look at the profiling API for Microsoft .NET runtime, as demanded by Michael Foord.

2007년 6월 4일 월요일

pyprof: Mono profiler for IronPython

CPython distribution comes with debuggers and profilers. More importantly, it comes with hooks so that you can write your own debuggers and profilers. You can set these hooks by built-in functions sys.settrace and sys.setprofile.

Here is what Python Library Reference says about sys.settrace (link):

settrace(tracefunc)

Set the system's trace function, which allows you to implement a Python source code debugger in Python. See section 24.2, "How It Works," in the chapter on the Python debugger. The function is thread-specific; for a debugger to support multiple threads, it must be registered using settrace() for each thread being debugged. Note: The settrace() function is intended only for implementing debuggers, profilers, coverage tools and the like. Its behavior is part of the implementation platform, rather than part of the language definition, and thus may not be available in all Python implementations.


In other words, another Python implementation like IronPython is within its own right not to implement these functions. As a matter of fact:

IronPython 1.1 (1.1) on .NET 2.0.50727.42
Copyright (c) Microsoft Corporation. All rights reserved.
>>> sys.settrace(f)
Traceback (most recent call last):
NotImplementedError: sys.settrace is not yet supported by IronPython
>>> sys.setprofile(f)
Traceback (most recent call last):
AttributeError: 'module' object has no attribute 'setprofile'


Don't get this wrong, this is fully okay. Both .NET Framework and Mono have their set of tools to do debugging, profiling, tracing, and coverage, often better than what CPython provides.

But when you debug a Python program, usually you don't need to single step inside Python runtime. When you trace a Python program, you don't necessarily want to know how a single line of Python code expands to 20 low-level function calls. So it's desirable to restrict tools to Python methods only.

Enter pyprof.

pyprof is a Mono profiler for IronPython. Mono provides an interface to write custom profilers, and there are quite some of them. pyprof uses this API to query a custom attribute, IronPython.Runtime.PythonModuleAttribute from method's defining assembly. Messages are printed only if the attribute is present.

The code is here:
https://fepy.svn.sourceforge.net/svnroot/fepy/trunk/pyprof/

Type "make test" to see what it can do. It should print the output in test.out file. (This assumes that you have blank site.py. The output will differ if you don't.)

Disclaimer: pyprof is a less-than-a-day old software. Don't expect much. But I do have great plans for this baby. :-)

Hello, world!

Due to peer pressure, I decided to start a blog. I will talk about the development of FePy project here.

FePy project