From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 65F537F30A for ; Wed, 13 Mar 2013 18:04:28 +0100 (CET) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of jon@ffconsultancy.com) identity=pra; client-ip=84.93.230.250; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="jon@ffconsultancy.com"; x-sender="jon@ffconsultancy.com"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of jon@ffconsultancy.com) identity=mailfrom; client-ip=84.93.230.250; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="jon@ffconsultancy.com"; x-sender="jon@ffconsultancy.com"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@avasout05.plus.net) identity=helo; client-ip=84.93.230.250; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="jon@ffconsultancy.com"; x-sender="postmaster@avasout05.plus.net"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AqAEALSwQFFUXeb6gWdsb2JhbABDxHYEgVoWDgEBFiYogjEIAh4SGzEFaCMcAQQeBYgIoUGGWppXjV0iB4EkgyoDjiWcMQ X-IPAS-Result: AqAEALSwQFFUXeb6gWdsb2JhbABDxHYEgVoWDgEBFiYogjEIAh4SGzEFaCMcAQQeBYgIoUGGWppXjV0iB4EkgyoDjiWcMQ X-IronPort-AV: E=Sophos;i="4.84,838,1355094000"; d="scan'208";a="7278461" Received: from avasout05.plus.net ([84.93.230.250]) by mail2-smtp-roc.national.inria.fr with ESMTP; 13 Mar 2013 18:04:27 +0100 Received: from XPS ([87.115.188.46]) by avasout05 with smtp id B54R1l00310W6AX0154Sj6; Wed, 13 Mar 2013 17:04:27 +0000 X-CM-Score: 0.00 X-CNFS-Analysis: v=2.0 cv=dpoF/Sc4 c=1 sm=1 a=pYon0QjUe1aYl5m7EDk53g==:17 a=yMYSIcTw4foA:10 a=Xub9RBUEA-sA:10 a=Kvk-SOs2Z7YA:10 a=kj9zAlcOel0A:10 a=r2vSxAw-AAAA:8 a=P4nwKl0Xik4A:10 a=OUd9heCtxyCn59SDWugA:9 a=CjuIK1q_8ugA:10 a=pYon0QjUe1aYl5m7EDk53g==:117 X-AUTH: jdh302:2500 Reply-To: From: "Jon Harrop" To: Date: Wed, 13 Mar 2013 17:04:26 -0000 Organization: Flying Frog Consultancy Ltd. Message-ID: <00ba01ce200c$d23f1910$76bd4b30$@ffconsultancy.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Outlook 14.0 Thread-Index: Ac1nKhT3pBJWDLXwSKiNrMxLxcnduQ== Content-Language: en-gb Subject: [Caml-list] Case study in optimization: porting a compiler from OCaml to F# There has been some discussion here about the implications of single- vs multi-threaded garbage collectors and, in particular, their performance in the context of the kinds of metaprogramming that OCaml has traditionally been used for. I recently ported a compiler written in OCaml to the F# programming language for a client and performance turned out to be an issue so I'd like to present this as a case study to provide some real data. Unfortunately I cannot disclose precise details. The original compiler was 15kLOC of OCaml code. The amounts of DSL code that it consumes and C code that it produces can be considerable and compilation can take minutes. Consequently, performance is valued by my client's customers and, therefore, the original code had been optimized for OCaml's performance characteristics. A direct translation of the OCaml code to F# proved to be over 10x slower. This was so slow that it impeded testing my translation so I did some optimization early. Specifically, profiling indicated that the biggest problem was the high rate of exceptions being raised and caught. Exceptions are around 600x slower on .NET than in OCaml so this can quickly degrade performance. I changed all of the hot paths to use union types (usually option types) instead of exceptions, according to F# idioms. Although this incurs a lot of unnecessary boxing in F# the performance improvements were substantial and the F# version became 5x slower than the OCaml. On a related note, thorough testing showed that my almost-blind translation of 15kLOC of code was completely error free. I think this is a real testament to the power of ML's static type system. The only error I have introduced so far occurred when I was replacing the use of an exception in a function with a union type. After demonstrating the correctness of the translation, my effort turned to trying to improve performance in an attempt to compete with the original OCaml code. I had believed that this could well prove to be prohibitively difficult or even impossible because symbolic code is OCaml's main strength. However, I have managed to make the F# around 8x faster than it was and, in particular, substantially faster than the original OCaml. So this non-trivial symbolic code base has not had its performance suffer from the adoption of a multicore-friendly garbage collector. -- Dr Jon Harrop, Flying Frog Consultancy Ltd. http://www.ffconsultancy.com