<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Lory’s Blob</title>
	<atom:link href="http://blog.lorentey.hu/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.lorentey.hu</link>
	<description></description>
	<lastBuildDate>Thu, 26 Jan 2012 15:51:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.lorentey.hu' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Lory’s Blob</title>
		<link>http://blog.lorentey.hu</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.lorentey.hu/osd.xml" title="Lory’s Blob" />
	<atom:link rel='hub' href='http://blog.lorentey.hu/?pushpress=hub'/>
		<item>
		<title>Efficient Scalar Attributes in Core Data</title>
		<link>http://blog.lorentey.hu/2010/10/31/core-data-scalars/</link>
		<comments>http://blog.lorentey.hu/2010/10/31/core-data-scalars/#comments</comments>
		<pubDate>Sun, 31 Oct 2010 01:11:04 +0000</pubDate>
		<dc:creator>lorentey</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.lorentey.hu/?p=331</guid>
		<description><![CDATA[I spent some time today on improving performance in my iOS development project, and I came up with some results that may be of interest to others working with Core Data. Note that the hacks demonstrated below are based on Time Profiler measurements taken on my (egregiously unoptimized) app under development. The underlying &#8220;performance issue&#8221; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=331&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I spent some time today on improving performance in my iOS development project, and I came up with some results that may be of interest to others working with Core Data. Note that the hacks demonstrated below are based on Time Profiler measurements taken on my (egregiously unoptimized) app under development. The underlying &#8220;performance issue&#8221; only occurs when you&#8217;re using standard Core Data scalar accessors unusually frequently, like my app did. It is overwhelmingly likely that your application does not exhibit the same behavior; therefore, please use Instruments to verify that read accessors are actually slowing down your app before applying any of these tweaks.</p>
<p><span id="more-331"></span></p>
<h2>Standard accessors</h2>
<p>Implementing accessors for scalar attributes in Core Data is somewhat inconvenient, as the framework only generates primitive accessors for scalars, and you&#8217;re supposed to write the normal accessors yourself, complete with correct access and change notifications.</p>
<p>The <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html">Core Data Programming Guide</a> recommends (in the <a href="http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdNSAttributes.html#//apple_ref/doc/uid/TP40001919-SW13">Scalar Values</a> section) that you implement scalar accessors like this:</p>
<pre>@interface MyManagedObject : NSManagedObject {
}
@property (nonatomic, assign) float x;
@property (nonatomic, assign) float primitiveX;
@end

@implementation
@dynamic primitiveX;

- (float)x {
    [self willAccessValueForKey:@"x"];
    float value = self.primitiveX;
    [self didAccessValueForKey:@"x"];
    return value;
}

- (void)setX:(float)value {
    [self willChangeValueForKey:@"x"];
    self.primitiveX = value;
    [self didChangeValueForKey:@"x"];
}
@end</pre>
<p>This works correctly, but if you&#8217;re using your attributes frequently, you may find that these accessors are surprisingly expensive. For example, I have an application that stores images in a Core Data database. The images consist of sets of bezier curves that are represented by a handful of model classes, each having several scalar attributes for the positions of their bezier control points. To debug performance issues, I wrote a little test case that repeatedly renders a complex image on a Core Graphics bitmap context. I knew that calling all those notifications can&#8217;t be very fast, but I was still surprised when I found that when I used accessors that follow the pattern above, those innocent-looking <code>willAccessValueForKey:</code> calls took close to a <em>third of my app&#8217;s entire running time</em>, more than all the graphics operations:</p>
<p><a href="http://lorentey.files.wordpress.com/2010/10/instruments-11.png"><img src="http://lorentey.files.wordpress.com/2010/10/instruments-11.png?w=497" alt="" title="[NSManagedObject willAccessValueForKey:] is slow as molasses"   class="aligncenter size-full wp-image-370" /></a></p>
<p>Apparently <code>willAccessValueForKey:</code> is somewhat slow because it needs to look up its <code>key</code> parameter in a table, and this lookup isn&#8217;t very efficient. (Judging by the topmost method name above, it looks like Core Data may support other (perhaps more efficient) mapping strategies. However, I don&#8217;t think there is a way to override the strategy that the framework chooses by default.)</p>
<p>Now obviously my app is somewhat of a pathological case, since (in its current unoptimized state) it enumerates all attributes of all objects multiple times during rendering, resulting in tens of thousands of <code>willAccessValueForKey:</code> calls to draw just a few hundred Bezier paths. But still, it is worth to find out what we can do to eliminate this overhead.</p>
<h2>Replace access notifications with explicit fetches</h2>
<p>As far as I know, <code>willAccessValueForKey:</code> is only used to fire faults when the object is not yet fully loaded into memory, and <code>didAccessValueForKey:</code> is simply a no-op. Thus, if you can be sure that your objects aren&#8217;t faults, then you can safely elide all <code>willAccessValueForKey:</code>/<code>didAccessValueForKey:</code> calls. One way of ensuring that there are no faults is to <a href="http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdPerformance.html#//apple_ref/doc/uid/TP40003468-SW6">prefetch</a> all objects before using them. (Prefetching also greatly improves performance when you&#8217;re iterating over a large set of items, like my drawing app does. With no prefetching, the profiler results above would have been swamped by Core Data using separate SQLite roundtrips to fetch each individual object.) Unfortunately it&#8217;s relatively easy to mistakenly prefetch less than you need, and accessing attribute values without firing the fault will result in bogus values that can be hard to debug.</p>
<p>For a more robust solution than simply removing access notifications, replace them by explicit fault checks. When a fault is discovered, trigger it before touching any attributes. To trigger a fault, simply call <code>willAccessValueForKey:</code> with a <code>nil</code> key. (Note that this only applies to read accessors; write accessors must keep using the original template above. You definitely don&#8217;t want to disable change notifications, because KVO and Core Data&#8217;s critical change tracking infrastructure rely on them.)</p>
<pre>@interface MyManagedObject : NSManagedObject {
}
@property (nonatomic, assign) float x;
@property (nonatomic, assign) float primitiveX;
- (void)fetch;
@end

@implementation
@dynamic primitiveX;

- (void)fetch {
    // Fire the fault.
    [self willAccessValueForKey:nil];
    [self didAccessValueForKey:nil];
}

- (float)x {
    if ([self isFault])
        [self fetch];
    return self.primitiveX;
}

- (void)setX:(float)value {
    [self willChangeValueForKey:@"x"];
    self.primitiveX = value;
    [self didChangeValueForKey:@"x"];
}
@end</pre>
<h2>Use instance variables</h2>
<p>While we are tweaking accessors, it may be worthwhile to represent performance-critical scalar attributes as instance variables, and access them directly whenever possible. To do this, simply declare the backing ivars, and override the primitive accessors so that they get and set attribute values using them. In the normal accessors, you can inline the primitive accessors instead of calling them to shave off a few extra nanoseconds spent in <code>objc_msgsend</code>.</p>
<p>The final code sample below uses ivars and also keeps track of the fault state in a separate boolean instance variable to let the read accessors work without any additional method calls in the usual case.</p>
<pre>@interface MyManagedObject : NSManagedObject {
    float _x;
    BOOL _fetched;
}
@property (nonatomic, assign) float x;
@property (nonatomic, assign) float primitiveX;
- (void)fetch;
@end

@implementation
- (void)fetch {
    // Fire the fault.
    [self willAccessValueForKey:nil];
    [self didAccessValueForKey:nil];
    _fetched = YES;
}

- (void)didTurnIntoFault {
    _fetched = NO;
    [super didTurnIntoFault];
}

- (float)primitiveX {
    return _x;
}

- (void)setPrimitiveX:(float)value {
    _x = value;
} 

- (float)x {
    if (!_fetched)
        [self fetch];
    return _x;
}

- (void)setX:(float)value {
    [self willChangeValueForKey:@"x"];
    self.primitiveX = value;
    [self didChangeValueForKey:@"x"];
}
@end</pre>
<h2>Results</h2>
<p>I implemented my Bezier path accessors to follow this last pattern, and additionally I changed my drawing methods to use ivars directly when possible (after a <code>_fetched</code> test) instead of calling accessors at all. At the end, I got this rather healthier looking Time Profiler output:</p>
<p><a href="http://lorentey.files.wordpress.com/2010/10/instruments-3.png"><img src="http://lorentey.files.wordpress.com/2010/10/instruments-3.png?w=497" alt="" title="We now spend much less time willAccessValueForKey:"   class="aligncenter size-full wp-image-365" /></a></p>
<p>The app&#8217;s running time is now dominated by bounding box calculations (<code>rcu</code>) and drawing operations, as expected. I can push down <code>willAccessValueForKey:</code> even further later by converting a few more attributes.</p>
<p>It is generally a bad idea to ignore the official way of doing things on iOS, but in my particular case the official approach turned out to be so slow that I had to find alternatives. As far as I can see, these hacks will continue to work fine until and unless Apple introduces new Core Data features that rely on access notifications. However, applying them in your project is a still a possible maintenance headache that is not worth risking unless you are 100% certain that standard read accessors have a measurable adverse effect on your overall performance. Don&#8217;t waste time and effort optimizing code that isn&#8217;t a performance bottleneck, especially not on the advice of random guys on the intertubes! If you do decide to use some of the above tweaks, use Instruments to measure performance before and after implementing all optimizations, and don&#8217;t be afraid to roll back your changes when (not if) they turn out to have no measurable effect.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lorentey.wordpress.com/331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lorentey.wordpress.com/331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lorentey.wordpress.com/331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lorentey.wordpress.com/331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lorentey.wordpress.com/331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lorentey.wordpress.com/331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lorentey.wordpress.com/331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lorentey.wordpress.com/331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lorentey.wordpress.com/331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lorentey.wordpress.com/331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lorentey.wordpress.com/331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lorentey.wordpress.com/331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lorentey.wordpress.com/331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lorentey.wordpress.com/331/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=331&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.lorentey.hu/2010/10/31/core-data-scalars/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0735d3bf1d76c0385258ac7a2a22d6fe?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">lory</media:title>
		</media:content>

		<media:content url="http://lorentey.files.wordpress.com/2010/10/instruments-11.png" medium="image">
			<media:title type="html">[NSManagedObject willAccessValueForKey:] is slow as molasses</media:title>
		</media:content>

		<media:content url="http://lorentey.files.wordpress.com/2010/10/instruments-3.png" medium="image">
			<media:title type="html">We now spend much less time willAccessValueForKey:</media:title>
		</media:content>
	</item>
		<item>
		<title>C++ Template Metaprogramming</title>
		<link>http://blog.lorentey.hu/2010/04/21/cpp-template-metaprogramming/</link>
		<comments>http://blog.lorentey.hu/2010/04/21/cpp-template-metaprogramming/#comments</comments>
		<pubDate>Tue, 20 Apr 2010 23:21:25 +0000</pubDate>
		<dc:creator>lorentey</dc:creator>
				<category><![CDATA[deranged]]></category>

		<guid isPermaLink="false">http://blog.lorentey.hu/?p=232</guid>
		<description><![CDATA[My close personal friend and colleague Encsé posted a fun little programming exercise and invited us to send him solutions in our favorite Turing-complete tool, especially if it happens to be mod_rewrite or C++ templates. Unfortunately, I don&#8217;t think there is a single sane person on the planet who would consider C++ their favorite anything, and I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=232&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>My <em>close personal friend</em> and colleague Encsé <a href="http://csokavar.hu/blog/2010/04/20/problem-of-the-week-9-digit-problem/">posted a fun little programming exercise</a> and invited us to send him solutions in our favorite Turing-complete tool, especially if it happens to be mod_rewrite or C++ templates. Unfortunately, I don&#8217;t think there is a single sane person on the planet who would consider C++ their favorite <em>anything</em>, and I like Encsé better than to let him needlessly associate with any additional crazy people. Obviously, this meant that I had to delve into the murky depths of template madness myself.</p>
<p>Here is a copy of the problem, in case Encsé decides to delete his post once he finds out it has been tainted with C++ — which would be an entirely sensible (and, indeed, healthy) reaction:</p>
<blockquote style="margin-left:30px;background:#F0F0F0;padding:6pt;"><p><em>Find a number consisting of 9 digits in which each of the digits from 1 to 9 appears only once. This number must also satisfy these divisibility requirements:</em></p>
<ol>
<li><em>The number should be divisible by 9.</em></li>
<li><em>If the rightmost digit is removed, the remaining number should be divisible by 8.</em></li>
<li><em>If the rightmost digit of the new number is removed, the remaining number should be divisible by 7.</em></li>
<li><em>And so on, until there’s only one digit (which will necessarily be divisible by 1).</em></li>
</ol>
</blockquote>
<p style="margin-top:12pt;">OK, so I implemented a solution using C++ template metaprogramming. It was actually easier than I thought, and the experience was surprisingly interesting. Which is not to say I&#8217;d like to do it again. I imagine I would feel this exact same way after performing an autopsy.</p>
<p><span id="more-232"></span></p>
<p>My approach encodes digits as template parameters using variadic templates, which are a recent addition to the language.  They make template metaprogramming more convenient the same way as a drop of mayonnaise would make a shit sandwich easier to swallow.</p>
<p>To make things easier to fit into the template syntax, the digits are encoded &#8220;backwards&#8221;, with the least significant digit to the left.  The interesting part is the <code>search</code> template, which implements a simple exhaustive search (based on lexically incrementing the digit list).  It trims the search space whenever a particular (partial) list of digits doesn&#8217;t satisfy the constraints above.  The solution is not particularly efficient, and since template tail recursion isn&#8217;t optimized away, you&#8217;ll probably need to increase the maximum depth of template expansion in your compiler.  (A limit of 2000 nested templates should be sufficient.)  I needed this many levels due to the clumsy recursive chaining that I do in the topmost definition of the <code>search_i</code> template, which is expanded whenever the search tree is trimmed.</p>
<pre style="margin-left:0;background-image:initial;background-repeat:initial;background-attachment:initial;background-color:#f0f0f0;height:400pt;font-size:9pt;line-height:10pt;background-position:initial initial;border:1px solid black;overflow:auto;padding:6pt;"><span style="color:#999999;font-style:italic;">// Author: karoly@lorentey.hu, 2010-04-20.
//
// To compile this, you'll need a recent C++ compiler supporting C++0x
// variadic templates.
//
// Sample command line for GCC 4.4:
//
// g++ -Wall -ftemplate-depth-2000 -std=c++0x -o 9digits 9digits.cc
</span><span class="pre">
#include &lt;iostream&gt;
</span><span style="color:#999999;font-style:italic;">
// value&lt;DIGITS&gt;::v is the value of DIGITS in decimal.
// The list starts with the least significant digit.
</span><span style="color:#990000;">template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span><span style="color:#663300;font-weight:bold;">...</span> digits<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> value<span style="color:#663300;font-weight:bold;">;</span><span style="color:#990000;">

template</span><span style="color:#663300;font-weight:bold;">&lt;&gt;</span><span style="color:#990000;">
struct</span> value<span style="color:#663300;font-weight:bold;">&lt;&gt;
{</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> int</span> v<span style="color:#663300;font-weight:bold;"> =</span><span style="color:#999900;"> 0</span><span style="color:#663300;font-weight:bold;">;
};</span><span style="color:#990000;">

template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span> first<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span><span style="color:#663300;font-weight:bold;">...</span> rest<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> value<span style="color:#663300;font-weight:bold;">&lt;</span>first<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;
{</span><span style="color:#990000;">
  static</span><span style="color:#ff6633;"> int</span><span style="color:#990000;"> const</span> v<span style="color:#663300;font-weight:bold;"> =</span><span style="color:#999900;"> 10</span><span style="color:#663300;font-weight:bold;"> *</span> value<span style="color:#663300;font-weight:bold;">&lt;</span>rest<span style="color:#663300;font-weight:bold;">...&gt;::</span>v<span style="color:#663300;font-weight:bold;"> +</span> first<span style="color:#663300;font-weight:bold;">;
};</span><span style="color:#999999;font-style:italic;">

// contains&lt;ELEM, SET&gt;::v is true if ELEM is in SET.
</span><span style="color:#990000;">template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span> elem<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span><span style="color:#663300;font-weight:bold;">...</span> set<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> contains<span style="color:#663300;font-weight:bold;">;</span><span style="color:#990000;">

template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span> elem<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> contains<span style="color:#663300;font-weight:bold;">&lt;</span>elem<span style="color:#663300;font-weight:bold;">&gt;
{</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> bool</span> v<span style="color:#663300;font-weight:bold;"> =</span><span style="color:#000000;font-weight:bold;"> false</span><span style="color:#663300;font-weight:bold;">;
};</span><span style="color:#990000;">

template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span> elem<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span> first<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span><span style="color:#663300;font-weight:bold;">...</span> rest<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> contains<span style="color:#663300;font-weight:bold;">&lt;</span>elem<span style="color:#663300;font-weight:bold;">,</span> first<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;
{</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> bool</span> v<span style="color:#663300;font-weight:bold;"> =</span> elem<span style="color:#663300;font-weight:bold;"> ==</span> first<span style="color:#663300;font-weight:bold;"> ||</span> contains<span style="color:#663300;font-weight:bold;">&lt;</span>elem<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;::</span>v<span style="color:#663300;font-weight:bold;">;
};</span><span style="color:#999999;font-style:italic;">

// divisor_test&lt;DIGITS&gt;::v is true if the number of digits
// in DIGITS is a divisor of their decimal value.
</span><span style="color:#990000;">template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span><span style="color:#663300;font-weight:bold;">...</span> digits<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> divisor_test<span style="color:#663300;font-weight:bold;">;</span><span style="color:#990000;">

template</span><span style="color:#663300;font-weight:bold;">&lt;&gt;</span><span style="color:#990000;">
struct</span> divisor_test<span style="color:#663300;font-weight:bold;">&lt;&gt;
{</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> bool</span> v<span style="color:#663300;font-weight:bold;"> =</span><span style="color:#000000;font-weight:bold;"> true</span><span style="color:#663300;font-weight:bold;">;
};</span><span style="color:#990000;">

template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span> first<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span><span style="color:#663300;font-weight:bold;">...</span> rest<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> divisor_test<span style="color:#663300;font-weight:bold;">&lt;</span>first<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;
{</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> int</span> num<span style="color:#663300;font-weight:bold;"> =</span> value<span style="color:#663300;font-weight:bold;">&lt;</span>first<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;::</span>v<span style="color:#663300;font-weight:bold;">;</span><span style="color:#990000;">

  static const</span><span style="color:#ff6633;"> int</span> div<span style="color:#663300;font-weight:bold;"> =</span><span style="color:#990000;"> sizeof</span><span style="color:#663300;font-weight:bold;">...(</span>rest<span style="color:#663300;font-weight:bold;">) +</span><span style="color:#999900;"> 1</span><span style="color:#663300;font-weight:bold;">;</span><span style="color:#990000;">

  static const</span><span style="color:#ff6633;"> int</span> mod<span style="color:#663300;font-weight:bold;"> =</span> num<span style="color:#663300;font-weight:bold;"> %</span> div<span style="color:#663300;font-weight:bold;">;</span><span style="color:#990000;">

  static const</span><span style="color:#ff6633;"> bool</span> v<span style="color:#663300;font-weight:bold;"> =</span> mod<span style="color:#663300;font-weight:bold;"> ==</span><span style="color:#999900;"> 0</span><span style="color:#663300;font-weight:bold;">;
};</span><span style="color:#999999;font-style:italic;">

// test_candidate&lt;FIRST, REST&gt;::v is true if cons(FIRST, REST) satisfies
// all constraints, assuming that REST already does.
</span><span style="color:#990000;">template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span> first<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span><span style="color:#663300;font-weight:bold;">...</span> rest<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> test_candidate<span style="color:#663300;font-weight:bold;">
{</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> bool</span> v<span style="color:#663300;font-weight:bold;"> = (</span>divisor_test<span style="color:#663300;font-weight:bold;">&lt;</span>first<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;::</span>v<span style="color:#663300;font-weight:bold;">
                         &amp;&amp; !</span>contains<span style="color:#663300;font-weight:bold;">&lt;</span>first<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;::</span>v<span style="color:#663300;font-weight:bold;">);
};</span><span style="color:#999999;font-style:italic;">

// search&lt;LENGTH, DIGITS&gt;::v is the first number that is greater or
// equal to the decimal value of DIGITS, satisifies all constraints
// and is of the given LENGTH.  (-1 if there is no such number.)
</span><span style="color:#990000;">template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span> length<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span><span style="color:#663300;font-weight:bold;">...</span> digits<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> search<span style="color:#663300;font-weight:bold;">;</span><span style="color:#990000;">

template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span> length<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> bool</span> good<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> bool</span> final<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span> digit<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span><span style="color:#663300;font-weight:bold;">...</span> rest<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> search_i<span style="color:#663300;font-weight:bold;">
{</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> int</span> v<span style="color:#663300;font-weight:bold;"> =</span> search<span style="color:#663300;font-weight:bold;">&lt;</span>length<span style="color:#663300;font-weight:bold;">,</span> digit<span style="color:#663300;font-weight:bold;"> +</span><span style="color:#999900;"> 1</span><span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;::</span>v<span style="color:#663300;font-weight:bold;">;
};</span><span style="color:#990000;">

template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span> length<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span> digit<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span><span style="color:#663300;font-weight:bold;">...</span> rest<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> search_i<span style="color:#663300;font-weight:bold;">&lt;</span>length<span style="color:#663300;font-weight:bold;">,</span><span style="color:#000000;font-weight:bold;"> true</span><span style="color:#663300;font-weight:bold;">,</span><span style="color:#000000;font-weight:bold;"> true</span><span style="color:#663300;font-weight:bold;">,</span> digit<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;
{</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> int</span> v<span style="color:#663300;font-weight:bold;"> =</span> value<span style="color:#663300;font-weight:bold;">&lt;</span>digit<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;::</span>v<span style="color:#663300;font-weight:bold;">;
};</span><span style="color:#990000;">

template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span> length<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span> digit<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span><span style="color:#663300;font-weight:bold;">...</span> rest<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> search_i<span style="color:#663300;font-weight:bold;">&lt;</span>length<span style="color:#663300;font-weight:bold;">,</span><span style="color:#000000;font-weight:bold;"> true</span><span style="color:#663300;font-weight:bold;">,</span><span style="color:#000000;font-weight:bold;"> false</span><span style="color:#663300;font-weight:bold;">,</span> digit<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;
{</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> int</span> v<span style="color:#663300;font-weight:bold;"> =</span> search<span style="color:#663300;font-weight:bold;">&lt;</span>length<span style="color:#663300;font-weight:bold;">,</span><span style="color:#999900;"> 1</span><span style="color:#663300;font-weight:bold;">,</span> digit<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;::</span>v<span style="color:#663300;font-weight:bold;">;
};</span><span style="color:#990000;">

template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span> length<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span> digit<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span><span style="color:#663300;font-weight:bold;">...</span> rest<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> search<span style="color:#663300;font-weight:bold;">&lt;</span>length<span style="color:#663300;font-weight:bold;">,</span> digit<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;
{</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> bool</span> good<span style="color:#663300;font-weight:bold;"> =</span> test_candidate<span style="color:#663300;font-weight:bold;">&lt;</span>digit<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;::</span>v<span style="color:#663300;font-weight:bold;">;</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> bool</span> final<span style="color:#663300;font-weight:bold;"> =</span> good<span style="color:#663300;font-weight:bold;"> &amp;&amp;</span><span style="color:#999900;"> 1</span><span style="color:#663300;font-weight:bold;"> +</span><span style="color:#990000;"> sizeof</span><span style="color:#663300;font-weight:bold;">...(</span>rest<span style="color:#663300;font-weight:bold;">) ==</span> length<span style="color:#663300;font-weight:bold;">;</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> int</span> v<span style="color:#663300;font-weight:bold;"> =</span> search_i<span style="color:#663300;font-weight:bold;">&lt;</span>length<span style="color:#663300;font-weight:bold;">,</span> good<span style="color:#663300;font-weight:bold;">,</span> final<span style="color:#663300;font-weight:bold;">,</span> digit<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;::</span>v<span style="color:#663300;font-weight:bold;">;
};</span><span style="color:#990000;">

template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span> length<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> search<span style="color:#663300;font-weight:bold;">&lt;</span>length<span style="color:#663300;font-weight:bold;">,</span><span style="color:#999900;"> 10</span><span style="color:#663300;font-weight:bold;">&gt;
{</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> int</span> v<span style="color:#663300;font-weight:bold;"> = -</span><span style="color:#999900;">1</span><span style="color:#663300;font-weight:bold;">;
};</span><span style="color:#990000;">

template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span> length<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span> next<span style="color:#663300;font-weight:bold;">,</span><span style="color:#ff6633;"> int</span><span style="color:#663300;font-weight:bold;">...</span> rest<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> search<span style="color:#663300;font-weight:bold;">&lt;</span>length<span style="color:#663300;font-weight:bold;">,</span><span style="color:#999900;"> 10</span><span style="color:#663300;font-weight:bold;">,</span> next<span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;
{</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> int</span> v<span style="color:#663300;font-weight:bold;"> =</span> search<span style="color:#663300;font-weight:bold;">&lt;</span>length<span style="color:#663300;font-weight:bold;">,</span> next<span style="color:#663300;font-weight:bold;"> +</span><span style="color:#999900;"> 1</span><span style="color:#663300;font-weight:bold;">,</span> rest<span style="color:#663300;font-weight:bold;">...&gt;::</span>v<span style="color:#663300;font-weight:bold;">;
};</span><span style="color:#990000;">

template</span><span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#ff6633;">int</span> length<span style="color:#663300;font-weight:bold;">&gt;</span><span style="color:#990000;">
struct</span> search<span style="color:#663300;font-weight:bold;">&lt;</span>length<span style="color:#663300;font-weight:bold;">&gt;
{</span><span style="color:#990000;">
  static const</span><span style="color:#ff6633;"> int</span> v<span style="color:#663300;font-weight:bold;"> =</span> search<span style="color:#663300;font-weight:bold;">&lt;</span>length<span style="color:#663300;font-weight:bold;">,</span><span style="color:#999900;"> 1</span><span style="color:#663300;font-weight:bold;">&gt;::</span>v<span style="color:#663300;font-weight:bold;">;
};</span><span style="color:#999999;font-style:italic;">

// This program eats cute kittens for breakfast.
</span><span style="color:#ff6633;">int</span><span style="color:#990000;">
main</span><span style="color:#663300;font-weight:bold;"> ()
{</span>
  std<span style="color:#663300;font-weight:bold;">::</span>cout<span style="color:#663300;font-weight:bold;"> &lt;&lt;</span> search<span style="color:#663300;font-weight:bold;">&lt;</span><span style="color:#999900;">9</span><span style="color:#663300;font-weight:bold;">&gt;::</span>v<span style="color:#663300;font-weight:bold;"> &lt;&lt;</span><span style="color:#009900;"> '\n'</span><span style="color:#663300;font-weight:bold;">;</span><span class="flow">

  return</span><span style="color:#999900;"> 0</span><span style="color:#663300;font-weight:bold;">;
}</span></pre>
<p>You can <a href="http://fnord.hu/9digits.cc">download the source</a> and try it yourself if you want. Your doctor would probably suggest that you don&#8217;t.</p>
<p>If you step back a few meters and squint your eyes a bit, the general approach may look a bit similar to that of a functional language like Haskell or Clean, except NOT AT ALL, WHAT THE HELL HAVE YOU BEEN SMOKING, STOP COMPARING THIS SENSELESS PERVERSION OF A LANGUAGE TO SOMETHING NAMED AFTER HASKELL CURRY, YOU DERANGED LUNATIC!!!</p>
<p>For shits and giggles I did some compilation benchmarks on my MacBook Pro (2.66 GHz Core 2 Duo, 4 GB). I don&#8217;t know how much time GCC version 4.3 needs to compile this&#8230; <em>thing</em>, because it still hasn&#8217;t finished, but amazingly, GCC 4.4 only required 6.9 seconds and about 115 MB RAM. This actually isn&#8217;t too bad at all, especially if you consider <a href="http://gergo.erdi.hu/blog/2010-04-19-unary_arithmetics_is_even_slower_than_you%27d_expect/">some of the alternatives</a>.</p>
<p>Those intertwined template specializations mean that for every list of digits that this algorithm evaluates, it creates a new specialization for the <code>value</code> template, the  <code>contains</code> template, the <code>divisor_test</code> template, et cetera, et cetera. To find the value of that single constant expression in the <code>main</code> function, the compiler ends up with thousands upon thousands of these little cross-referencing one-off types. Fortunately, each of them consists of one or more static const members, and none of these structs are ever instantiated, so all traces of them can be completely eliminated from the compiled object file. </p>
<p>All the interesting stuff happens inside the compiler, and the end result is an executable file that is equivalent to the slightly less cuckoo (but unfortunately still C++) program below. GCC 4.4 compiles this trivial program in 0.25 seconds, which is (only!) about thirty times faster than the abomination listed above. GCC is getting pretty good these days, isn&#8217;t it?</p>
<pre style="margin-left:0;background-image:initial;background-repeat:initial;background-attachment:initial;background-color:#f0f0f0;font-size:9pt;line-height:10pt;background-position:initial initial;border:1px solid black;overflow:auto;padding:6pt;"><span class="pre">#include &lt;iostream&gt;
</span><span style="color:#ff6633;">
int</span><span style="color:#990000;">
main</span><span style="color:#663300;font-weight:bold;"> ()
{
</span>  <span style="color:#999999;font-style:italic;">// SPOILERS!</span>
  std<span style="color:#663300;font-weight:bold;">::</span>cout<span style="color:#663300;font-weight:bold;"> &lt;&lt;</span><span style="color:#999900;"> 381654729</span><span style="color:#663300;font-weight:bold;"> &lt;&lt;</span><span style="color:#009900;"> '\n'</span><span style="color:#663300;font-weight:bold;">;</span><span class="flow">
  return</span><span style="color:#999900;"> 0</span><span style="color:#663300;font-weight:bold;">;
}</span></pre>
<p>(Incidentally, a C version that uses printf instead of these mysterious shift operators compiles in under 0.04 secs. I like C. C likes me. You always know where you are with C.)</p>
<p>I could prove that these programs produce the same results by posting the compiler&#8217;s assembly outputs, but publishing C++ disassembly is against the Universal Declaration of Human Rights. Compile them and see for yourself, if you dare.</p>
<p><em>Is this a clever trick?</em> Yeah, it&#8217;s undoubtedly pretty clever.</p>
<p><em>Is this approach useful in real life?</em> Well, there are some considerably less insane use cases. Boost has some <a href="http://www.boost.org/doc/libs/1_42_0?view=category_Function-objects">well-written examples</a>.</p>
<p><em>Is it a good idea to use these kinds of language hacks in any project that you or your company depend on?</em> Absolutely not. For example, Boost also includes a rich variety of lovingly hand-crafted <a href="http://www.boost.org/doc/libs/1_42_0/libs/preprocessor/doc/index.html">C preprocessor hacks</a>. Using C++ template metaprogramming for anything serious is at least as good an idea as using any of those. For best (i.e., worst) effect, try combining the power of templates <em>and</em> the C preprocessor!</p>
<p>Let this post serve as a warning for us all. Please do not use C++ at home. Or at work. Especially not at work.</p>
<p>As far as members of the C language family go, I&#8217;m staying with C, Objective C, Java and C#, thank you very much. I hear D is also pretty nice.</p>
<p><strong>Update:</strong> GCC 4.3 finished in 15 minutes and 54 seconds, consuming 1.5 GB of address space.  Hurray for progress!</p>
<p><strong>Update 2:</strong> Cactus has created a <a href="http://gergo.erdi.hu/cs/ninedigits/lorentey-c%2B%2B-tmp/lorentey-c%2B%2B-tmp.hs">Haskell version of this algorithm</a>. Its beauty contrasts nicely with the morbid ugliness of the C++ version.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lorentey.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lorentey.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lorentey.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lorentey.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lorentey.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lorentey.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lorentey.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lorentey.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lorentey.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lorentey.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lorentey.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lorentey.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lorentey.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lorentey.wordpress.com/232/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=232&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.lorentey.hu/2010/04/21/cpp-template-metaprogramming/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0735d3bf1d76c0385258ac7a2a22d6fe?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">lory</media:title>
		</media:content>
	</item>
		<item>
		<title>BlueRemote Is Now Free Software</title>
		<link>http://blog.lorentey.hu/2010/04/19/blueremote-is-now-free-software/</link>
		<comments>http://blog.lorentey.hu/2010/04/19/blueremote-is-now-free-software/#comments</comments>
		<pubDate>Mon, 19 Apr 2010 09:32:48 +0000</pubDate>
		<dc:creator>lorentey</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.lorentey.hu/?p=219</guid>
		<description><![CDATA[Just a few years ago, Palm OS had a large user base and an active third-party developer community, with tens of thousands of apps available from multiple, open application stores, most prominently PalmGear.com. The OS was used on small mobile devices from PDAs and GPS systems to fancy smartphones — it was a nice system [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=219&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Just a few years ago, Palm OS had a large user base and an active third-party developer community, with tens of thousands of apps available from multiple, open application stores, most prominently <a href="http://palmgear.com">PalmGear.com</a>. The OS was used on small mobile devices from PDAs and GPS systems to fancy smartphones — it was a nice system that was cutting edge in the nineties, but by 2004, it has become horribly outdated. PalmSource&#8217;s efforts to introduce OS 6 — a version with a modern, 32-bit, multitasking, memory protecting architecture — proved futile: no Palm OS 6-based device was ever produced. By 2006, Palm has mostly switched to producing Windows Mobile phones. Then in 2007 the iPhone happened, and its brilliant user experience and centralized, integrated App Store instantly made all Palm OS devices still on the market obsolete.</p>
<p>All this means that in 2010 it may seem a tiny bit too late to publish Palm OS source code. Thankfully the system still has a small group of enthusiastic users who work on keeping the platform alive.  To this very day, I&#8217;m still regularly contacted about my old Bluetooth remote control application, which I sadly didn&#8217;t keep updated to run on the last few generations of devices.  It&#8217;s great that people care about my work, and the least I can do is to let them take control.</p>
<p><span id="more-219"></span></p>
<p>So here is a bunch of source code, now relicensed under GPL version 2. I should have done this years ago!</p>
<p><a href="http://code.google.com/p/blue-remote">http://code.google.com/p/blue-remote</a></p>
<p>I find the source to be surprisingly readable, which is a good sign (I haven&#8217;t looked at it in years).</p>
<p>For old times&#8217; sake I hope to find some time to install a current Palm OS SDK and work on BlueRemote a bit myself.  In the meantime, please play with it, study it, change it, fix it or pervert it however you fancy. It would be awesome if you contributed your changes back to the &#8220;official&#8221; project — so by all means contact me if you want to be a project member.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lorentey.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lorentey.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lorentey.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lorentey.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lorentey.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lorentey.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lorentey.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lorentey.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lorentey.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lorentey.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lorentey.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lorentey.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lorentey.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lorentey.wordpress.com/219/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=219&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.lorentey.hu/2010/04/19/blueremote-is-now-free-software/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0735d3bf1d76c0385258ac7a2a22d6fe?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">lory</media:title>
		</media:content>
	</item>
		<item>
		<title>Javítsuk meg az iPhone magyar billentyűzetét!</title>
		<link>http://blog.lorentey.hu/2010/04/18/iphone-magyar-kiosztas/</link>
		<comments>http://blog.lorentey.hu/2010/04/18/iphone-magyar-kiosztas/#comments</comments>
		<pubDate>Sun, 18 Apr 2010 16:17:45 +0000</pubDate>
		<dc:creator>lorentey</dc:creator>
				<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.lorentey.hu/?p=200</guid>
		<description><![CDATA[Néhány szavasnál hosszabb magyar szöveget gépelni iPhone-on pokolian nehéz dolog, mert az ékezetes betűket nem lehet közvetlenül bepötyögni. Az alapbetűt nyomva tartva a kb. fél másodperc szünet után felugró menüből ki tudjuk választani a kívánt ékezetes változatot, de ez nagyon megszakítja a gépelés lendületét. A magyar nyelvben az ékezetes betűk gyakorisága kb. 11.383% — ez [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=200&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://lorentey.files.wordpress.com/2010/04/new-iphone-hungarian-layout.png"><img class="alignleft size-full wp-image-201" title="Hungarian layout for iPhone" src="http://lorentey.files.wordpress.com/2010/04/new-iphone-hungarian-layout.png?w=497" alt=""   /></a>Néhány szavasnál hosszabb magyar szöveget gépelni iPhone-on pokolian nehéz dolog, mert az ékezetes betűket nem lehet közvetlenül bepötyögni. Az alapbetűt nyomva tartva a kb. fél másodperc szünet után felugró menüből ki tudjuk választani a kívánt ékezetes változatot, de ez nagyon megszakítja a gépelés lendületét. A magyar nyelvben az <a href="http://bsstudio.virtus.hu/index.php?id=detailed_article&amp;aid=62638">ékezetes betűk gyakorisága</a> kb. 11.383% — ez alig marad el a leggyakoribb E betű 12.256%-ától. Átlagban minden nyolcadik-kilencedik betűt tehát csak ilyen nyakatekert, lassú módszerrel tudjuk begépelni, ami a gyakorlatban ahhoz vezet, hogy inkább nem is használunk ékezeteket.</p>
<p><span id="more-200"></span></p>
<p>A jelenlegi billentyűzetkiosztás tehát nem jó. Szerencsére érintőképernyős billentyűzetet nem nehéz javítani, csak a szoftvert kell megváltoztatni. De hogy nézne ki az ideális magyar billentyűzet? Sajnos a képernyő viszonylag kis mérete miatt nem volna járható út mind a kilenc ékezetes betűnek saját gombot adni: ehhez túlzottan össze kellene nyomni a gombok méretét, és az apró billentyűket talán még a jelenlegi megoldásnál is frusztrálóbb volna használni.</p>
<p>Ha kirándulunk egyet a telefon beállításai között, és bekapcsoljuk a cseh kiosztást, egy zseniális megoldásra lelhetünk:</p>
<p style="text-align:center;"><a href="http://lorentey.files.wordpress.com/2010/04/chech.png"><img class="aligncenter size-full wp-image-206" title="Cseh kiosztás" src="http://lorentey.files.wordpress.com/2010/04/chech.png?w=497" alt=""   /></a></p>
<p style="text-align:left;">A második és harmadik sor egy-egy extra billentyűje segítségével építhetjük fel a cseh ékezetes betűket. Amikor megnyomjuk őket, az előttük álló alapbetű tetejére egy vessző ill. egy hacsek kerül, így észvesztően könnyen és gyorsan tudunk gépelni. Az így felépített ékezeteket az alapbetűtől függetlenül lehet törölni, így a véletlenül hibásan bevitt ékezeteket is nagyon egyszerű kijavítani.</p>
<p>A magyar változathoz nem kettő, hanem három extra billentyűre volna szükség, de egy kis turkálással találhatunk ilyen kiosztásra is példát. Íme a dán billentyűzet:</p>
<p style="text-align:center;"><a href="http://lorentey.files.wordpress.com/2010/04/danish.png"><img class="aligncenter size-full wp-image-208" title="Dán billentyűzet" src="http://lorentey.files.wordpress.com/2010/04/danish.png?w=497" alt=""   /></a></p>
<p>Ezen kiosztáson a gombok egy kicsit keskenyebbek, mert felső sorban helyet kellett csinálni az Å betűnek.  Szerencsére ez nem rontja jelentősen a gépelés élményét (pláne nem fektetett üzemmódban), úgyhogy az extra gombokat cseh kiosztáshoz hasonlóan működő ékezetekre cserélve remek magyar billentyűzetet kapnánk:</p>
<p style="text-align:center;"><a href="http://lorentey.files.wordpress.com/2010/04/hungarian.png"><img class="aligncenter size-full wp-image-209" title="Magyar billentyűzet" src="http://lorentey.files.wordpress.com/2010/04/hungarian.png?w=497" alt=""   /></a></p>
<p>Már csak az a kérdés, hogyan változtathatjuk meg a telefon kiosztását. Az App Store sajnos nem támogatja új billentyűzetkiosztások rendszerszintű telepítését, de az Apple a tapasztalatok szerint meggyőzhető arról, hogy érdemes fejleszteni, ha elegendő számú megfontolt és udvarias hangvételű felhasználói visszajelzést kap. Úgyhogy bátran ragadjunk tollat, és <a href="http://www.apple.com/feedback/iphone.html">töltsük ki a megfelelő űrlapot</a> (lehetőleg angolul)! A 4.0-ás iPhone OS-be már nem férne bele egy ilyen módosítás, de a 4.1-be biztosan.</p>
<p>Az igazi, hardveres billentyűzettel rendelkező telefonokon nem volt költséghatékony csak a magyar piac kedvéért extra gombokat tenni, de szerencsére érintőképernyőkön már ennek semmi akadálya nincs. Fogjunk össze, és tegyük ezt a kiosztást szabványossá az érintőképernyős telefonokban!</p>
<p><strong>Update:</strong> A fejlesztő kollégák a 8134383-as bug reportot is megdupe-olhatják a <a href="https://bugreport.apple.com/">radaron</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lorentey.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lorentey.wordpress.com/200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lorentey.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lorentey.wordpress.com/200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lorentey.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lorentey.wordpress.com/200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lorentey.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lorentey.wordpress.com/200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lorentey.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lorentey.wordpress.com/200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lorentey.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lorentey.wordpress.com/200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lorentey.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lorentey.wordpress.com/200/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=200&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.lorentey.hu/2010/04/18/iphone-magyar-kiosztas/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0735d3bf1d76c0385258ac7a2a22d6fe?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">lory</media:title>
		</media:content>

		<media:content url="http://lorentey.files.wordpress.com/2010/04/new-iphone-hungarian-layout.png" medium="image">
			<media:title type="html">Hungarian layout for iPhone</media:title>
		</media:content>

		<media:content url="http://lorentey.files.wordpress.com/2010/04/chech.png" medium="image">
			<media:title type="html">Cseh kiosztás</media:title>
		</media:content>

		<media:content url="http://lorentey.files.wordpress.com/2010/04/danish.png" medium="image">
			<media:title type="html">Dán billentyűzet</media:title>
		</media:content>

		<media:content url="http://lorentey.files.wordpress.com/2010/04/hungarian.png" medium="image">
			<media:title type="html">Magyar billentyűzet</media:title>
		</media:content>
	</item>
		<item>
		<title>Logitech Touch Mouse</title>
		<link>http://blog.lorentey.hu/2010/01/31/logitech-touch-mouse/</link>
		<comments>http://blog.lorentey.hu/2010/01/31/logitech-touch-mouse/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 17:18:18 +0000</pubDate>
		<dc:creator>lorentey</dc:creator>
				<category><![CDATA[BlueRemote]]></category>

		<guid isPermaLink="false">http://blog.lorentey.hu/?p=182</guid>
		<description><![CDATA[My stupid little six years old idea is now a Logitech product on the iPhone. My original implementation on ancient Palm PDAs/smartphones emulated a standard Bluetooth peripheral and it did not need special software running on the computer — similar apps on the iPhone work over WiFi and require starting up special server programs.  This [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=182&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>My stupid little six years old idea is now a <a href="http://blog.logitech.com/2010/01/29/new-logitech-touch-mouse-turns-your-iphone-or-ipod-touch-into-a-wireless-trackpad-and-keyboard">Logitech product</a> on the iPhone.</p>
<p><img class="alignright" src="http://fnord.hu/BlueRemote.gif" alt="" width="320" height="320" /></p>
<p>My original implementation on ancient Palm PDAs/smartphones emulated a standard Bluetooth peripheral and it did not need special software running on the computer — similar apps on the iPhone work over WiFi and require starting up special server programs.  This is to be expected, since Palm supported third-party applications accessing the Bluetooth radio (they even provided a reasonably convenient &amp; full-featured API for it), while Apple does not.  This is, at the end, a good thing: there is a limit to what an Apple-blessed app can do to an iPhone.  Buggy Palm applications could and did frequently crash the device.  There was a proliferation of third-party hacks that hooked into system internals and changed essential system behaviour, invariably destabilizing it.  The Treo was a great toy, but a horrible phone — I had to reset it multiple times per day and learned not to rely on it for anything important.  I can&#8217;t even remember when I last rebooted my iPhone.</p>
<p>The royalty checks I received for BlueRemote over all these years have paid back the price of the development kit (i.e., my Tungsten T2 and Treo 650), with perhaps just a little extra.  I believe this was considered a success back then, considering that I did not do any marketing whatsoever.   BlueRemote&#8217;s price was $14, with (AFAICR) 60% going to Motricity&#8217;s pockets.  For contrast, the going price for similar software in the App Store is 1$, with 70% going to the developer.  (The Logitech app is for promoting their hardware, so it&#8217;s free.)  The fact that it still seems worthwhile for one-man teams to produce software for 0.7$ a pop is a testament to the App Store&#8217;s success.</p>
<p>Once in a while, I still get an email complaining that BlueRemote does not work on the <a href="http://en.wikipedia.org/wiki/Treo_680">lastest generation</a> of Palm OS devices, with their fancy new Bluetooth chips. It would be mildly amusing to fix this at some point and release an update.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lorentey.wordpress.com/182/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lorentey.wordpress.com/182/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lorentey.wordpress.com/182/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lorentey.wordpress.com/182/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lorentey.wordpress.com/182/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lorentey.wordpress.com/182/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lorentey.wordpress.com/182/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lorentey.wordpress.com/182/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lorentey.wordpress.com/182/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lorentey.wordpress.com/182/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lorentey.wordpress.com/182/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lorentey.wordpress.com/182/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lorentey.wordpress.com/182/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lorentey.wordpress.com/182/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=182&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.lorentey.hu/2010/01/31/logitech-touch-mouse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0735d3bf1d76c0385258ac7a2a22d6fe?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">lory</media:title>
		</media:content>

		<media:content url="http://fnord.hu/BlueRemote.gif" medium="image" />
	</item>
		<item>
		<title>Ezt hallgattam 2009-ben</title>
		<link>http://blog.lorentey.hu/2010/01/30/ezt-hallgattam-2009-ben/</link>
		<comments>http://blog.lorentey.hu/2010/01/30/ezt-hallgattam-2009-ben/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 09:23:07 +0000</pubDate>
		<dc:creator>lorentey</dc:creator>
				<category><![CDATA[duruzsol]]></category>

		<guid isPermaLink="false">http://blog.lorentey.hu/?p=159</guid>
		<description><![CDATA[FYI, a last.fm szerint ezeket az előadókat hallgattam 2009-ben: Ugyanez hónapokra lebontva: Végezetül itt egy montázs a legtöbbet hallgatott előadóimmal 2004 és 2010 között: (eredetileg ez egy szép, klikkelhető image map volt, de a szuper-duper wordpress.com-nak kiütése lesz az ilyen modern HTML fogásoktól.) Hát nem lebilincselő diagramok?   Jól látható, hogy szeretem, ha őszülő, hosszú hajú férfiak [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=159&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>FYI, a <a href="http://www.last.fm/user/fnordfnord">last.fm</a> szerint ezeket az előadókat hallgattam 2009-ben:</p>
<p style="text-align:center;"><a href='http://lorentey.files.wordpress.com/2010/01/fnordfnord_music_universe.pdf'><img class="aligncenter size-full wp-image-171" title="Music Universe 2009" src="http://lorentey.files.wordpress.com/2010/01/music-universe-2009.png?w=497" alt=""   /></a></p>
<p>Ugyanez hónapokra lebontva:</p>
<p style="text-align:center;"><a style="text-decoration:none;" href="http://lorentey.files.wordpress.com/2010/01/fnordfnord_listening_trends.pdf"><img class="aligncenter size-full wp-image-169" title="Listening Trends 2009" src="http://lorentey.files.wordpress.com/2010/01/map.png?w=497" alt=""   /></a></p>
<p>Végezetül itt egy montázs a legtöbbet hallgatott előadóimmal 2004 és 2010 között: (eredetileg ez egy szép, klikkelhető image map volt, de a szuper-duper wordpress.com-nak kiütése lesz az ilyen modern HTML fogásoktól.)</p>
<p style="text-align:center;"><a href="http://lorentey.files.wordpress.com/2010/01/artist-collage-2004-2010.jpeg"><img class="aligncenter size-full wp-image-174" title="Artist Collage 2004–2010" src="http://lorentey.files.wordpress.com/2010/01/artist-collage-2004-2010.jpeg?w=497" alt=""   /></a></p>
<p>Hát nem lebilincselő diagramok?   Jól látható, hogy szeretem, ha őszülő, hosszú hajú férfiak duruzsolnak a fülembe!  (Mellesleg fogalmam sem volt, hogy olyan sok <a href="http://en.wikipedia.org/wiki/Stephen_Lynch_(musician)">Stephen Lynchet</a> hallgatok, hogy már a top 20-be is bekerült — megyek, le is törlöm a telefonomról.)</p>
<p>A lejátszások számára alapuló statisztikák egyébként egy kicsit félrevezetőek, mert már évek óta sokkal több időt töltök podcastek hallgatásával, mint zenével.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lorentey.wordpress.com/159/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lorentey.wordpress.com/159/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lorentey.wordpress.com/159/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lorentey.wordpress.com/159/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lorentey.wordpress.com/159/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lorentey.wordpress.com/159/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lorentey.wordpress.com/159/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lorentey.wordpress.com/159/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lorentey.wordpress.com/159/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lorentey.wordpress.com/159/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lorentey.wordpress.com/159/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lorentey.wordpress.com/159/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lorentey.wordpress.com/159/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lorentey.wordpress.com/159/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=159&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.lorentey.hu/2010/01/30/ezt-hallgattam-2009-ben/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0735d3bf1d76c0385258ac7a2a22d6fe?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">lory</media:title>
		</media:content>

		<media:content url="http://lorentey.files.wordpress.com/2010/01/music-universe-2009.png" medium="image">
			<media:title type="html">Music Universe 2009</media:title>
		</media:content>

		<media:content url="http://lorentey.files.wordpress.com/2010/01/map.png" medium="image">
			<media:title type="html">Listening Trends 2009</media:title>
		</media:content>

		<media:content url="http://lorentey.files.wordpress.com/2010/01/artist-collage-2004-2010.jpeg" medium="image">
			<media:title type="html">Artist Collage 2004–2010</media:title>
		</media:content>
	</item>
		<item>
		<title>Politika 2.</title>
		<link>http://blog.lorentey.hu/2010/01/29/politika-2/</link>
		<comments>http://blog.lorentey.hu/2010/01/29/politika-2/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 21:11:11 +0000</pubDate>
		<dc:creator>lorentey</dc:creator>
				<category><![CDATA[bitang]]></category>

		<guid isPermaLink="false">http://blog.lorentey.hu/?p=155</guid>
		<description><![CDATA[A legutóbbi bnapló-bejegyzésemben megfogalmazott problémámat Miklósi Gábor bőbeszédűbben is megírta az Indexen.  Minden szava arany, bár aránytalanul sokat foglalkozik egy „SZDSZ” nevű párttal, ami csak valami szarkasztikus indexes poén lehet. Egyik magyar pártra sem lehet jó szívvel szavazni.  Nincs legkisebb rossz.  És az a leginkább borzasztó, hogy a kampány csak most kezdődik: ennél már csak [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=155&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://blog.lorentey.hu/2010/01/27/politika/">legutóbbi bnapló-bejegyzésemben</a> megfogalmazott problémámat Miklósi Gábor <a href="http://index.hu/velemeny/2010/01/25/befogott_orral_halkan_anyazva/">bőbeszédűbben is megírta</a> az Indexen.  Minden szava arany, bár aránytalanul sokat foglalkozik egy „SZDSZ” nevű párttal, ami csak valami szarkasztikus indexes poén lehet.</p>
<p>Egyik magyar pártra sem lehet jó szívvel szavazni.  Nincs legkisebb rossz.  És az a leginkább borzasztó, hogy a kampány csak most kezdődik: ennél már csak lejjebb süllyedhetnek.</p>
<p><a href="http://cerka.blog.hu/2008/03/11/homokos_vagy_bitang_szavazolapon_elhelyezett_nepmuveszeti_firkak_elemzese"><img alt="" src="http://m.blog.hu/ce/cerka/image/200803/nepszavkur.jpg" title="Pina!" class="aligncenter" width="600" height="480" /></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lorentey.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lorentey.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lorentey.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lorentey.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lorentey.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lorentey.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lorentey.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lorentey.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lorentey.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lorentey.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lorentey.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lorentey.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lorentey.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lorentey.wordpress.com/155/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=155&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.lorentey.hu/2010/01/29/politika-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0735d3bf1d76c0385258ac7a2a22d6fe?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">lory</media:title>
		</media:content>

		<media:content url="http://m.blog.hu/ce/cerka/image/200803/nepszavkur.jpg" medium="image">
			<media:title type="html">Pina!</media:title>
		</media:content>
	</item>
		<item>
		<title>Politika</title>
		<link>http://blog.lorentey.hu/2010/01/27/politika/</link>
		<comments>http://blog.lorentey.hu/2010/01/27/politika/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 00:59:37 +0000</pubDate>
		<dc:creator>lorentey</dc:creator>
				<category><![CDATA[garancialevél]]></category>

		<guid isPermaLink="false">http://blog.lorentey.hu/?p=139</guid>
		<description><![CDATA[NSFW kampánymellékletünket hallják. Amiért meg sem fordul a fejemben, hogy a Fideszre szavazzak Amiért meg sem fordul a fejemben, hogy az MSZP-re szavazzak Amiért meg sem fordul a fejemben, hogy a Jobbikra szavazzak Amiért meg sem fordul a fejemben, hogy az MDF-re szavazzak Amiért meg sem fordul a fejemben, hogy a KDNP-re szavazzak Amiért meg [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=139&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>NSFW kampánymellékletünket hallják.</p>
<p><a href="http://lorentey.files.wordpress.com/2010/01/broaf.jpg">Amiért meg sem fordul a fejemben, hogy a Fideszre szavazzak</a></p>
<p><a href="http://www.origo.hu/attached/20060917oszod5.mp3">Amiért meg sem fordul a fejemben, hogy az MSZP-re szavazzak</a></p>
<p><a href="http://kuruc.info">Amiért meg sem fordul a fejemben, hogy a Jobbikra szavazzak</a></p>
<p><a href="http://www.fn.hu/belfold/20081013/lengyel_zoltan_megmenti_mdf/">Amiért meg sem fordul a fejemben, hogy az MDF-re szavazzak</a></p>
<p><a href="http://semjenzsolt.hu/">Amiért meg sem fordul a fejemben, hogy a KDNP-re szavazzak</a></p>
<p><a href="http://www.youtube.com/watch?v=1wapCSmPEmg">Amiért meg sem fordul a fejemben, hogy az LMP-re szavazzak</a></p>
<p><a href="http://www.charonboat.com/item/135">Amiért meg sem fordul a fejemben, hogy az MKMP-re szavazzak</a></p>
<p><a href="http://bombagyar.hu/">Amiért meg sem fordul a fejemben, hogy a Zöld Pártra szavazzak</a></p>
<p>Kihagytam valakit?  Párthívek ellenvéleménye?</p>
<p>Egyelőre úgy fest, a <a href="http://www.lemonparty.vze.com/">Lemon Party</a> vagy az <a href="http://www.freeweb.hu/ketfarkukutya/part/mkkpmxfeltort.swf">MKKP</a> fog ikszet kapni tőlem.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lorentey.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lorentey.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lorentey.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lorentey.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lorentey.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lorentey.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lorentey.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lorentey.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lorentey.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lorentey.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lorentey.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lorentey.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lorentey.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lorentey.wordpress.com/139/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=139&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.lorentey.hu/2010/01/27/politika/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0735d3bf1d76c0385258ac7a2a22d6fe?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">lory</media:title>
		</media:content>
	</item>
		<item>
		<title>Menger App</title>
		<link>http://blog.lorentey.hu/2009/12/02/menger-app/</link>
		<comments>http://blog.lorentey.hu/2009/12/02/menger-app/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 15:49:55 +0000</pubDate>
		<dc:creator>lorentey</dc:creator>
				<category><![CDATA[spongya]]></category>

		<guid isPermaLink="false">http://blog.lorentey.hu/?p=115</guid>
		<description><![CDATA[Én sem szeretnék lemaradni a bimbózó Menger mémről, úgyhogy íme egy screenshot az iPhone legújabb mindentvivő alkalmazásáról, a Menger Appról. Bizonyára Önnel is számtalanszor előfordult már, hogy egy mindig a Föld középpontja felé forduló, fekete ködbe vesző, artériás vér színű harmadfokú Menger spongya-közelítést szeretett volna megfigyelni, de épp egyetlen ilyen sem volt a közelben. A Menger [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=115&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Én sem szeretnék lemaradni a <a href="http://gergo.erdi.hu/blog/2009-12-01-adventi_menger-szivacs/">bimbózó</a> <a href="http://fogaskerek.blog.hu/2009/12/02/adventi_kocka_kockaknak">Menger mémről</a>, úgyhogy íme egy screenshot az iPhone legújabb mindentvivő alkalmazásáról, a Menger Appról.</p>
<p>Bizonyára Önnel is számtalanszor előfordult már, hogy egy mindig a Föld középpontja felé forduló, fekete ködbe vesző, artériás vér színű harmadfokú <a href="http://en.wikipedia.org/wiki/Menger_sponge">Menger spongya</a>-közelítést szeretett volna megfigyelni, de épp egyetlen ilyen sem volt a közelben. A Menger App segítségével ezentúl bármikor kielégítheti ezirányú vágyait!</p>
<p>A Menger App az iTunes App Store-ban nem hozzáférhető, csak elit kiválasztottak egy szűk köre juthat hozzá. Kápráztassa el barátait!  Menger App!</p>
<p style="text-align:center;"><a href="http://lorentey.files.wordpress.com/2009/12/menger.png"><img class="aligncenter size-full wp-image-114" title="Menger Sponge" src="http://lorentey.files.wordpress.com/2009/12/menger.png?w=497" alt=""   /></a></p>
<p>Igazából persze csak a móricka 3D motorom kipróbálásához kellett valami bonyolultabb tesztmodell, amihez kapóra jött, hogy mindenki Menger-lázban ég körülöttem. Nosza kitaláltam hogyan lehet leírni a szivacs felületét adó poligonokat, és a kapott rekurzív algoritmust egy borzasztó ronda Python szkripttel jól meg is implementáltam. A módszer érdekessége, hogy a triviális, kockákból építkező megoldással ellentétben csak a szivacs tényleges felületét generálja, a belső, láthatatlan lapokat kihagyja. További érdekesség, hogy a szivacs közelítéseinek felszínén lépten-nyomon megfigyelhető, nyolc négyzetből is kirakható „lyukas négyzet” formát a program az alábbi nyolc, láncba fűzhető háromszöggel írja le, ezzel is csökkentve a kimenet méretét:</p>
<p style="text-align:center;"><a style="text-decoration:none;" href="http://lorentey.files.wordpress.com/2009/12/lukas.png"><img class="aligncenter size-full wp-image-126" title="Lukas négyzet" src="http://lorentey.files.wordpress.com/2009/12/lukas.png?w=497" alt=""   /></a></p>
<p>Ezzel együtt is például a fenti harmadfokú közelítés eredménye 46 848 csúcspontból áll, amik 27 648 háromszöget feszítenek ki. (A negyedfokú változat ugyanezzel a módszerrel 912 384 csúcsból és 528 384 háromszögből állna.) Sok persze a duplikált csúcs, és nagyon-nagyon megérné egy utófeldolgozási menetben hosszabb háromszögláncokat is keresni, de a célnak a modell így is megfelel.</p>
<p>Az alkalmazás az előzőleg legenerált kész modellfájlt egyszerűen be-mmapolja a címterébe, aztán a kapott blokkot simán vertex arrayként használja.</p>
<p>Mint kiderült, ez a kevesebb, mint 30 000 háromszög pont elég ahhoz, hogy 13-15 fps mellett 100%-ra kihajtsa az iPhone 3G grafikus gyorsító csipjének transzformáló egységét, miközben a processzor terhelése 50% alatt marad. A verem-minták szerint VBO-k használata esetén is a CPU javarészben folyamatosan vektoradatokkal eteti a segédprocesszort, tehát a VBO-k az iPhone-on nem érnek kutyafülét sem. Ez mondjuk egy dedikált grafikus memória nélküli gépen nem is annyira meglepő.</p>
<p>Ráadásul a szivacsmodellben pillanatnyilag minden csúcs mellett egy normálvektort is transzformálni kell, tehát a GPU majdnem dupla annyi melót végez, mintha csak a csúcsokat számolná. Ezt persze teljesen feleslegesen teszi, hiszen a spongyában csak hatféle normálvektor van, és ezek közül egyszerre csak legfeljebb öt ad a képernyőn is nyomot hagyó háromszöget.  A screenshoton pl. csak háromféle irányultságú háromszög látható, a többi a kamerától elfelé néz. Ezeket helyből ki lehetne zárni a megjelenítésből, kár is őket elküldeni az MBX-nek.</p>
<p>Ha a háromszögláncok maximalizálása mellett a normálvektorokat sem csúcsonként adnám meg, hanem irányultságonként különválogatnám a pontokat, szerintem simán meglehetne a stabil 25-30 fps – de ez egyelőre maradjon házi feladat.</p>
<p>A <a href="http://www.glbenchmark.com/phonedetails.jsp?benchmark=glpro&amp;D=Apple%20iPhone%203G&amp;testgroup=lowlevel">sebességtesztek</a> szerint az iPhone 3G végsebességben olyan 680 000 háromszöget képes feldolgozni másodpercenként. Ehhez képest az én 15 * 27 648 = 414 720 eredményem lópikula, de ez a fenti optimalizálási lehetőségek alapján nem olyan meglepő.  Az viszont nagyon meglepett, hogy az <a href="http://www.glbenchmark.com/phonedetails.jsp?benchmark=glpro11&amp;D=Apple%20iPhone%203G%20S&amp;testgroup=lowlevel">elvileg sokszorta gyorsabb</a> 3GS modellen a változatlan tesztprogramom még a 3G-nél is 1-2 fps-sel lassabban fut!  Na ezt magyarázza meg nekem valaki.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lorentey.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lorentey.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lorentey.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lorentey.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lorentey.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lorentey.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lorentey.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lorentey.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lorentey.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lorentey.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lorentey.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lorentey.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lorentey.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lorentey.wordpress.com/115/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=115&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.lorentey.hu/2009/12/02/menger-app/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0735d3bf1d76c0385258ac7a2a22d6fe?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">lory</media:title>
		</media:content>

		<media:content url="http://lorentey.files.wordpress.com/2009/12/menger.png" medium="image">
			<media:title type="html">Menger Sponge</media:title>
		</media:content>

		<media:content url="http://lorentey.files.wordpress.com/2009/12/lukas.png" medium="image">
			<media:title type="html">Lukas négyzet</media:title>
		</media:content>
	</item>
		<item>
		<title>Lejárat az S&amp;M kazamatákhoz</title>
		<link>http://blog.lorentey.hu/2009/12/02/lejarat-az-sm-kazamatakhoz/</link>
		<comments>http://blog.lorentey.hu/2009/12/02/lejarat-az-sm-kazamatakhoz/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 12:20:13 +0000</pubDate>
		<dc:creator>lorentey</dc:creator>
				<category><![CDATA[pix]]></category>

		<guid isPermaLink="false">http://lorentey.wordpress.com/?p=106</guid>
		<description><![CDATA[Oktogon, Budapest<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=106&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-364" src="http://lorentey.files.wordpress.com/2009/12/p_1600_1200_9f4a2890-82e9-4f99-b173-85fc4e129ac0.jpeg?w=497" alt=""   /></p>
<p>Oktogon, Budapest</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lorentey.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lorentey.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/lorentey.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/lorentey.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/lorentey.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/lorentey.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/lorentey.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/lorentey.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/lorentey.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/lorentey.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/lorentey.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/lorentey.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/lorentey.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/lorentey.wordpress.com/106/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.lorentey.hu&amp;blog=10120058&amp;post=106&amp;subd=lorentey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.lorentey.hu/2009/12/02/lejarat-az-sm-kazamatakhoz/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0735d3bf1d76c0385258ac7a2a22d6fe?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">lory</media:title>
		</media:content>

		<media:content url="http://lorentey.files.wordpress.com/2009/12/p_1600_1200_9f4a2890-82e9-4f99-b173-85fc4e129ac0.jpeg" medium="image" />
	</item>
	</channel>
</rss>
