Java code ported to Objective-C is very slow - cocoa

I want to illustrate a concrete example to understand if there are best (and worst) practices when java code is rewritten in Objective-C.
I've ported the Java implementation of org.apache.wicket.util.diff.myers to Objective-C on OSX Snow Leopard (Xcode 4) but the result runs very slowly compared to the Java version.
The method with worst performances is buildPath, it mainly does
sparse array access (diagonal variable, this array is allocated inside method and isn't returned)
random array access (orig and rev variables)
allocation of PathNode and its subclasses (an object with three properties, only property is an element using internally by array)
strings comparison
Cocoa hasn't any collection class to work easily with sparse arrays so I've allocated an array with malloc, this dramatically improved the first version based on NSDictionary and zillion of NSNumber's object allocated to be used as key.
The PathNode(s) allocation is done using the normal syntax [[MyClass alloc] init], they aren't autoreleased because are added to an NSMutableArray (but are released immediately after adding it to array)
Random access to array is done using [NSArray objectAtIndex:index] I think (but I can be wrong) that moving it to an C-like doesn't speedup so much.
Do you have any idea to improve performance, where bottlenecks can be found?
Using instruments 74% of time is spent on allocation, how can I improve allocation?
EDIT I've submitted my actual implementation to github, obviously is an alpha version not ready for production and doesn't use any efficient objective-c construct

You're off to an excellent start. You've profiled the code, isolated the actual bottleneck, and are now focused on how to address it.
The first question is which allocation is costly? Obviously you should focus on that one first.
There are several efficient ways to deal with sparse arrays. First, look at NSPointerArray, which is designed to hold NULL values. It does not promise to be efficient for sparse arrays, but #bbum (who knows such things) suggests it is.
Next, look at NSHashMap, which is certainly efficient for sparse collections (it's a dictionary), and supports non-object keys (i.e. you don't need to create an NSNumber).
Finally, if allocation really is your problem, there are various tricks to work around it. The most common is to reuse objects rather than destroying one and creating another. This is how UITableViewCell works (and NSCell in a different way).
Finally, if you switch to Core Foundation objects, you can create your own specialized memory allocator, but that really is a last resort.
Note that 10.6 supports ARC (without zeroing weak references). ARC dramatically improves performance around a lot of common memory management patterns. For example, the very common pattern of "retain+autorelease+return" is highly optimized under ARC. ("retain" doesn't exist in the language in ARC, but it does still exist in the compiler, and ARC is much faster than doing by hand.) I highly recommend switching to ARC in any code you can.

You can use the NSPointerArray class as a replacement for your sparse array. NSPointerArray allows null elements.
If you post the code thats generating the bulk of your allocations, we might be able to help you more.

Related

Can a Swift object have arbitrary inline storage in the instance?

For example, an immutable CFString can store the length and the character data in the same block of memory. And, more generally, there is NSAllocateObject(), which lets you specify extra bytes to be allocated after the object’s ivars. The amount of storage is determined by the particular instance rather than being fixed by the class. This reduces memory use (one allocation instead of two) and improves locality of reference. Is there a way to do this with Swift?
A rather later reply. 😄 NSAllocateObject() is now deprecated for some reason. However, NSAllocateObject() is really a wrapper around class_createInstance which is not deprecated. So, in principle, one could use this to allocate extra bytes for an object instance.
I can't see why this wouldn't work in Swift. But accessing the extra storage would be messy because you'd have to start fooling around with unsafe pointers and the like. Moreover, if you're not the author of the original class, then you risk conflicting with Apple's ivars, especially in cases where you might be dealing with a class cluster which could potentially have a number of different instance sizes, according to the specific concrete implementation.
I think a safter approach would be to make use of objc_setAssociatedObject and objc_getAssociatedObject, which are accessible in Swift. E.g. Is there a way to set associated objects in Swift?

There is a fast way to use Clojure vectors as matrices?

I am trying to use Clojure to process images and I would like to represent images using Clojure data structures. Basically, my first approach was using a vector of vectors and mapv to operate over each pixel value and return a new image representation with the same data structure. However, some basic operations are taking too much time.
Using Jvisual profiler, I got the results showed below. Somebody could give me a tip to improve the performance? I can give more details if it is necessary, but maybe just looking at the costs of seq and next someone can have a good guess.
You should check out core.matrix and associated libraries for anything to do with matrix computation. core.matrix is a general purpose Clojure API for matrix computation, supporting multiple back-end implementations.
Clojure's persistent data structures are great for most purposes, but are really not suited for fast processing of large matrices. The main problems are:
Immutability: usually a good thing, but can be a killer for low level code where you need to do things like accumulate results in a mutable array for performance reasons.
Boxing: Clojure data structures generally box results (as java.lang.Double etc.) which adds a lot of overhead compared to using primitives
Sequences: traversing most Clojure data structures as sequences involved the creation of temporary heap objects to hold the sequence elements. Normally not a problem, but when you are dealing with large matrices it becomes problematic.
The related libraries that you may want to look at are:
vectorz-clj : a very fast matrix library that works as a complete core.matrix implementation. The underlying code is pure Java but with a nice Clojure wrapper. I believe it is currently the fastest way of doing general purpose matrix computation in Clojure without resorting to native code. Under the hood, it uses arrays of Java primitives, but you don't need to deal with this directly.
Clatrix: another fast matrix library for Clojure which is also a core.matrix implementation. Uses JBLAS under the hood.
image-matrix : represents a Java BufferedImage as a core.matrix implementation, so you can perform matrix operations on images. A bit experimental right now, but should work for basic use cases
Clisk : a library for procedural image processing. Not so much a matrix library itself, but very useful for creating and manipulating digital images using a Clojure-based DSL.
Depending on what you want to do, the best approach may be to use image-matrix to convert the images into vectorz-clj matrices and do your processing there. Alternatively, Clisk might be able to do what you want out of the box (it has a lot of ready-made filters / distortion effects etc.)
Disclaimer: I'm the lead developer for most of the above libraries. But I'm using them all myself for serious work, so very willing to vouch for their usefulness and help fix any issues you find.
I really think that you should use arrays of primitives for this. Clojure has array support built-in, even though it's not highlighted, and it's for cases just like this, where you have a high volume of numerical data.
Any other approach, vectors, even java collections will result in all of your numbers being boxed individually, which is very wasteful. Arrays of primitives (int, double, byte, whatever is appropriate) don't have this problem, and that's why they're there. People feel shy about using arrays in clojure, but they're there for a reason, and this is it. And it'll be good protable clojure code -- int-array works in both jvm clojure and clojure-script.
Try arrays and benchmark.
Clojure's Transients offer a middle ground between full persistence and no persistence like you would get with a standard java array. This allows you to build the image using fast mutate-in-place opperations (which are limited to the current thread) and then call persistent! to convert it in constante time to a proper persistent structure for manipulation in the rest of the program
It looks like you are also seeing a lot of overhead from working with sequences over the contents of the image, if transients don't make enough of a difference you may want to next consider using normal java arrays and structure the accesses to directly access the array elements.

Overhead of memory allocator

I've been creating a temporary object stack- mainly for the use of heap-based STL structures which only actually have temporary lifetimes, but any other temporary dynamically sized allocation too. The one stack performs all types- storing in an unrolled linked list.
I've come a cropper with alignment. I can get the alignment with std::alignment_of<T>, but this isn't really great, because I need the alignment of the next type I want to allocate. Right now, I've just arbitrarily sized each object at a multiple of 16, which as far as I know, is the maximal alignment for any x86 or x64 type. But now, I'm having two pointers of memory overhead per object, as well as the cost of allocating them in my vector, plus the cost of making every size round up to a multiple of 16.
On the plus side, construction and destruction is fast and reliable.
How does this compare to regular operator new/delete? And, what kind of test suites can I run? I'm pretty pleased with my current progress and don't want to find out later that it's bugged in some nasty subtle fashion, so any advice on testing the operations would be nice.
This doesn't really answer your question, but Boost has just recently added a memory pool library in the most recent version.
It may not be exactly what you want, but there is a thorough treatment of alignment which might spark an idea? If the docs are not enough, there is always the source code.

what is less resource intensive: Bindings, KVO, or Notifications

Rather than trying to run a bunch of tests. Does anybody know what is less resource intensive?
Bindings, KVO, or Notifications? Has anyone tested to see as well?
Chuck's answer is quite right as far as notifications vs. KVO goes, but I'd like to expand on the "Bindings are KVO + KVC + ..." part he mentioned because that's where the real pain in the ass can be. Key Value Coding seems like it's the more important consideration here, since you can't use Bindings without it. If you're worrying about performance for good reasons, you'd do well to note the cost heavy use of KVC can incur.
I would say that any circumstances that call for heavy querying as a result of a single action (example: asking a few thousand objects for the results of multiple key paths each) would be an indicator that you might want to avoid KVC (and Bindings by extension). Especially with long key paths ( -valueForKeyPath: vs. -valueForKey: ).
I've run hard up against this myself and am now working to eliminate this part of my architecture as a result. The relatively minute cost of Key Value Coding can seriously add up when you're asking 16,000 objects for the result of half a dozen long key paths as a result of a button press (even with NSOperation/Queue). The difference between using KVC and good-old-fashioned [[object message] message...] calls can mean the difference between a few seconds and well over a minute or two on large jobs. For me, the very same query calling the accessors directly (like [parameter name] or [[parameter variable] name]) represented roughly a 500% increase in speed. Granted, mine is quite a complex data model with a large volume of data for a typical document.
On the other hand, if many of your app's single actions affect/query one or a handful of objects and are mostly Key Value Observing-oriented (ie, change a last name and have it update in a few views at once), its simplicity can be akin to magic.
In summary: if your app queries/updates large volumes of data, you might do better to avoid KVC and Bindings for the query/update part because of KVC, not because of KVO.
On OS X, it doesn't generally matter. They're all lightweight. Apple itself relies on it, and so the implementations are highly optimized. I would write the code so that it is as readable as possible, and only optimize the speed/resource consumption when it's necessary.
Another point is that Apple often changes the implementation across the OS version. So, the relative cost (speed, resource consumption etc.) of various particular technologies often change. What can be found on the 'net can be often outdated. Apple itself emphasizes never to assume which is faster and lighter, and instead to use profiler (Instruments, etc.) to measure the bottleneck yourself.
These aren't really distinct options, per se. KVO is a special case of notifications. Bindings are KVO + KVC + a couple of glue classes.

What are your strategies to keep the memory usage low?

Ruby is truly memory-hungry - but also worth every single bit.
What do you do to keep the memory usage low? Do you avoid big strings and use smaller arrays/hashes instead or is it no problem to concern about for you and let the garbage collector do the job?
Edit: I found a nice article about this topic here - old but still interesting.
I've found Phusion's Ruby Enterprise Edition (a fork of mainline Ruby with much-improved garbage collection) to make a dramatic difference in memory usage... Plus, they've made it extraordinarily easy to install (and to remove, if you find the need).
You can find out more and download it on their website.
I really don't think it matters all that much.
Making your code less readable in order to improve memory consumption is something you should only ever do if you need it. And by need, I mean have a specific case for the performance profile and specific metrics that indicate that any change will address the issue.
If you have an application where memory is going to be the limiting factor, then Ruby may not be the best choice. That said, I have found that my Rails apps generally consume about 40-60mb of RAM per Mongrel instance. In the scheme of things, this isn't very much.
You might be able to run your application on the JVM with JRuby - the Ruby VM is currently not as advanced as the JVM for memory management and garbage collection. The 1.9 release is adding many improvements and there are alternative VM's under development as well.
Choose date structures that are efficient representations, scale well, and do what you need.
Use algorithms that work using efficient data structures rather than bloated, but easier ones.
Look else where. Ruby has a C bridge and its much easier to be memory conscious in C than in Ruby.
Ruby developers are quite lucky since they don’t have to manage the memory themselves.
Be aware that ruby allocates objects, for instance something as simple as
100.times{ 'foo' }
allocates 100 string objects (strings are mutable and each version requires its own memory allocation).
Make sure that if you are using a library allocating a lot of objects, that other alternatives are not available and your choice is worth paying the garbage collector cost. (you might not have a lot of requests/s or might not care for a few dozen ms per requests).
Creating a hash object really allocates more than an object, for instance
{'joe' => 'male', 'jane' => 'female'}
doesn’t allocate 1 object but 7. (one hash, 4 strings + 2 key strings)
If you can use symbol keys as they won’t be garbage collected. However because they won’t be garbage collected you want to make sure to not use totally dynamic keys like converting the username to a symbol, otherwise you will ‘leak’ memory.
Example: Somewhere in your app, you apply a to_sym on an user’s name like :
hash[current_user.name.to_sym] = something
When you have hundreds of users, that’s could be ok, but what is happening if you have one million of users ? Here are the numbers :
ruby-1.9.2-head >
# Current memory usage : 6608K
# Now, add one million randomly generated short symbols
ruby-1.9.2-head > 1000000.times { (Time.now.to_f.to_s).to_sym }
# Current memory usage : 153M, even after a Garbage collector run.
# Now, imagine if symbols are just 20x longer than that ?
ruby-1.9.2-head > 1000000.times { (Time.now.to_f.to_s * 20).to_sym }
# Current memory usage : 501M
Be aware to never convert non controlled arguments in symbol or check arguments before, this can easily lead to a denial of service.
Also remember to avoid nested loops more than three levels deep because it makes the maintenance difficult. Limiting nesting of loops and functions to three levels or less is a good rule of thumb to keep the code performant.
Here are some links in regards:
http://merbist.com
http://blog.monitis.com
When deploying a Rails/Rack webapp, use REE or some other copy-on-write friendly interpreter.
Tweak the garbage collector (see https://www.engineyard.com/blog/tuning-the-garbage-collector-with-ruby-1-9-2 for example)
Try to cut down the number of external libraries/gems you use since additional code uses memory.
If you have a part of your app that is really memory-intensive then it's maybe worth rewriting it in a C extension or completing it by invoking other/faster/better optimized programs (if you have to process vast amounts of text data, maybe you can replace that code with calls to grep, awk, sed etc.)
I am not a ruby developer but I think some techniques and methods are true of any language:
Use the minimum size variable suitable for the job
Destroy and close variables and connections when not in use
However if you have an object you will need to use many times consider keeping it in scope
Any loops with manipulations of a big string dp the work on a smaller string and then append to bigger string
Use decent (try catch finally) error handling to make sure objects and connections are closed
When dealing with data sets only return the minimum necessary
Other than in extreme cases memory usage isn't something to worry about. The time you spend trying to reduce memory usage will buy a LOT of gigabytes.
Take a look at Small Memory Software - Patterns for Systems with Limited Memory. You don't specify what sort of memory constraint, but I assume RAM. While not Ruby-specific, I think you'll find some useful ideas in this book - the patterns cover RAM, ROM and secondary storage, and are divided into major techniques of small data structures, memory allocation, compression, secondary storage, and small architecture.
The only thing we've ever had which has actually been worth worrying about is RMagick.
The solution is to make sure you're using RMagick version 2, and call Image#destroy! when you're done using your image
Avoid code like this:
str = ''
veryLargeArray.each do |foo|
str += foo
# but str << foo is fine (read update below)
end
which will create each intermediate string value as a String object and then remove its only reference on the next iteration. This junks up the memory with tons of increasingly long strings that have to be garbage collected.
Instead, use Array#join:
str = veryLargeArray.join('')
This is implemented in C very efficiently and doesn't incur the String creation overhead.
UPDATE: Jonas is right in the comment below. My warning holds for += but not <<.
I'm pretty new at Ruby, but so far I haven't found it necessary to do anything special in this regard (that is, beyond what I just tend to do as a programmer generally). Maybe this is because memory is cheaper than the time it would take to seriously optimize for it (my Ruby code runs on machines with 4-12 GB of RAM). It might also be because the jobs I'm using it for are not long-running (i.e. it's going to depend on your application).
I'm using Python, but I guess the strategies are similar.
I try to use small functions/methods, so that local variables get automatically garbage collected when you return to the caller.
In larger functions/methods I explicitly delete large temporary objects (like lists) when they are no longer needed. Closing resources as early as possible might help too.
Something to keep in mind is the life cycle of your objects. If you're objects are not passed around that much, the garbage collector will eventually kick in and free them up. However, if you keep referencing them it may require some cycles for the garbage collector to free them up. This is particularly true in Ruby 1.8, where the garbage collector uses a poor implementation of the mark and sweep technique.
You may run into this situation when you try to apply some "design patterns" like decorator that keep objects in memory for a long time. It may not be obvious when trying example in isolation, but in real world applications where thousands of objects are created at the same time the cost of memory growth will be significant.
When possible, use arrays instead of other data structures. Try not to use floats when integers will do.
Be careful when using gem/library methods. They may not be memory optimized. For example, the Ruby PG::Result class has a method 'values' which is not optimized. It will use a lot of extra memory. I have yet to report this.
Replacing malloc(3) implementation to jemalloc will immediately decrease your memory consumption up to 30%. I've created 'jemalloc' gem to achieve this instantly.
'jemalloc' GEM: Inject jemalloc(3) into your Ruby app in 3 min
I try to keep arrays & lists & datasets as small as possible. The individual object do not matter much, as creation and garbage collection is pretty fast in most modern languages.
In the cases you have to read some sort of huge dataset from the database, make sure to read in a forward/only manner and process it in little bits instead og loading everything into memory first.
dont use a lot of symbols, they stay in memory until the process gets killed.. this because symbols never get garbage collected.

Resources