Skip to content

Latest commit

 

History

History
207 lines (160 loc) · 6.25 KB

README.md

File metadata and controls

207 lines (160 loc) · 6.25 KB

Goop

Description

The Goop (Go Object-Oriented Programming) package provides support for dynamic object-oriented programming constructs in Go, much like those that appear in various scripting languages. The goal is to integrate fast, native-Go objects and slower but more flexible Goop objects within the same program.

Features

Goop provides the following features, which are borrowed from an assortment of object-oriented programming languages:

  • a prototype-based object model

  • support for both ex nihilo and constructor-based object creation

  • the ability to add, replace, and remove data fields and method functions at will

  • multiple inheritance

  • dynamically modifiable inheritance hierarchies (even on a per-object basis)

  • type-dependent dispatch (i.e., multiple methods with the same name but different argument types)

Installation

If necessary, set the GOROOT environment variable to the directory containing src/Make.inc and src/Make.pkg. Afterwards, you can follow the usual Go package installation procedure, running either a simple

    goinstall github.com/losalamos/goop

or the longer

    git clone http://github.com/losalamos/goop $GOROOT/src/pkg/github.com/losalamos/goop
    cd $GOROOT/src/pkg/github.com/losalamos/goop
    gomake
    gotest
    gomake install

It is then safe to do a gomake clean.

Documentation

Pre-built documentation for the Goop API is available online at http://gopkgdoc.appspot.com/pkg/github.com/losalamos/goop, courtesy of GoPkgDoc.

Once you install Goop, you can view the API locally with godoc, for example by running

    godoc goop

to display the Goop documentation on screen or by running

    godoc -http=:6060

to start a local Web server then viewing the HTML-formatted documentation at http://localhost:6060/pkg/github.com/losalamos/goop/ in your favorite browser.

Performance

Goop is unfortunately extremely slow. Goop programs have to pay for their flexibility in terms of performance. To determine just how bad the performance is on your computer, you can run the microbenchmarks included in goop_test.go:

    gotest -test.bench=".*" -test.benchtime=5

On my computer, I get results like the following (reformatted for clarity):

    goop.BenchmarkNativeFNV1          2000000000       2.94 ns/op
    goop.BenchmarkNativeFNV1Closure   1000000000       6.11 ns/op
    goop.BenchmarkGoopFNV1              50000000     203    ns/op
    goop.BenchmarkMoreGoopFNV1           5000000    1425    ns/op
    goop.BenchmarkEvenMoreGoopFNV1       1000000    4594    ns/op

See goop_test.go for the complete source code for those benchmarks. Basically,

  • BenchmarkNativeFNV1 is native (i.e., non-Goop) Go code for computing a 64-bit FNV-1 hash on a sequence of 0xFF bytes. Each iteration ("op" in the performance results) comprises a nullary function call, a multiplication by a large prime number, and an exclusive or with an 0xFF byte.

  • BenchmarkNativeFNV1Closure is the same but instead of calling an ordinary function each iteration, it invokes a locally defined closure.

  • BenchmarkGoopFNV1 defines a Goop object that contains a single data field (the current hash value) and no methods. Each iteration performs one Get and one Set on the Goop object.

  • BenchmarkMoreGoopFNV1 replaces the hash function with an object method. Hence, each iteration performs one Get, one Set, and one Call on the Goop object.

  • BenchmarkEvenMoreGoopFNV1 adds support for type-dependent dispatch to the hash-function method. Although only one type signature is defined, Goop has to confirm at run time that the provided arguments do in fact match that signature.

Another way to interpret the data shown above is that, on my computer at least, a function closure costs about 3 ns; Get and Set each cost approximately 100 ns; a Call of a nullary function costs about 1200 ns; and type-dependent dispatch costs an additional 3200 ns.

How does Goop compare to various scripting languages? Not well, at least for BenchmarkMoreGoopFNV1 and its equivalents in other languages. The following table shows the cost in nanoseconds of an individual BenchmarkMoreGoopFNV1 operation (a function call, a read of a data field, a 64-bit multiply, an 8-bit exclusive or, and a write to a data field):

Language Run time (ns/op)
[Incr Tcl] 8.5.9 25730
Ruby 1.8.7 1613
Go weekly.2011-11-09 + Goop 1425
Perl 5.10.1 900
JavaScript 1.4 (Rhino 1.7) 738
Python 2.7.1 685
Ruby 1.9.1 519
Python 2.7.1 + PyPy 503

In short, you'll want to do most of your coding in native Go and use Goop only when your application requires the extra flexibility that Goop provides. Then, you should cache as many object members as possible in Go variables to reduce the number of Get and Set calls.

License

Goop is provided under a BSD-ish license with a "modifications must be indicated" clause. See http://github.com/losalamos/goop/blob/master/LICENSE for the full text.

Author

Scott Pakin, pakin@lanl.gov