15 Jan 2013
About one month ago, we were given the opportunity to participate in
Seedcamp Paris 2012. In this post I’ll try to
think back to that time and provide feedback, along with some advice if you’re
considering going in that direction. In short, I can already say that this
experience has revolutionized the way we drive the company!

The Application
Everything starts with a good application… or a rushed one in our case! At
that time (end of October) we were fully focused on product development and
finishing everything needed for our launch (documentation, video, etc.). While
we knew about Seedcamp coming to Paris in early December, we initially saw it
as a potential distraction from more important stuff… we could not have been
more wrong!
Our opinion changed after a lunch with Philippe
Laval, former Seedcamp alumni with his
company Kwaga (now WriteThat.name, whom I had
the pleasure to meet a few times in my previous jobs. In a couple of hours,
Philippe opened our eyes to the broad requirements for successfully launching
a startup. Product is clearly one, but there are so many others we could not
ignore. His description of how his Seedcamp participation helped him a few
years back was enough to convince us we had to give it a shot.
Each step of the process brought its own rewards, starting with the
application! It is a simple form but it contains excellent questions about
positioning, monetization, competition and more. The best thing about it was
that we were forced to write down our vision for the company and this simple
process made us think harder than we had ever done before. We ended up
convincing ourselves more fully of what we were doing and why, with facts and
arguments to defend our vision. Of course, we would present the company
completely differently today! We continued to learn at an accelerated pace in
the following weeks. Despite some imperfections, participating in a Seedcamp
final is definitely a must.
The Almighty Pitch Preparation
About a couple of weeks before the event, we received the good news: we were
in! The promise to keep our success confidential was a bit frustrating, but
honestly we were overjoyed! However, there was no time to celebrate as
preparations for the event began immediately.
We already knew about the format and what to expect from the Seedcamp team
from what we gathered on the web. But there is a great leap from knowing to
actually preparing to participate! And with all the regular day-(to-night-)to-
day activities that our startup entailed, time was short.
We started by focusing on the pitch: 3 minutes, in English, to say a lot. We
rapidly drafted a first version and began to iterate, adding essential
information and removing anything not worth mentioning. It may seem
straightforward, but including everything from the problem, solution, vision,
market, competition, monetization and team in a three minute deck is no easy
task. It is, however, an excellent way to learn how to better explain your
startup! We learned to be concise - every word counts, and I began to memorize
each and every one of them. I had given speeches of various kinds on many
occasions in the past but I had never learned a text by heart. If you’ve never
done it before, it is more difficult than you may think. For a long time, I
was so concerned to get the wording right that any mistake would send me
fumbling for my next words. I had to practice dozens of times to feel
comfortable enough to pay attention to simple things like intonation!
Some advice: start working on your pitch as early as possible and get as much
feedback as you can. We were able to organize some pitch training sessions
with startup personalities and I can’t stress how useful this proved to be!
(Our greatest thanks to Wessel,
Liam,
Philippe and
Fred. But wait, isn’t there a
training session on the eve of the event? Yes, and it is incredibly useful.
But if you don’t like the idea of changing everything overnight, work on your
draft and seek feedback beforehand! The preparation session will be all the
more focused for it. Also, if you can, do test your presentation with the
actual computer and projector that will be used the next day. While in our
case the conference room was really nice, the projector was very low-res and
our embedded video would not render at all. Fortunately we had the time to
record a new one with all fonts in bold…
Prepare your Mentoring Session too!
Out of the 20 teams participating, only two or three get an investment, so the
odds are tough. You may be lucky and seduce the Seedcamp team, but if not
don’t waste your opportunity to get the most out of the mentoring sessions!
This is an incredible opportunity: about 80 mentors, many of them expert in
some field key to the success of your company, and all there ready to help.
Believe me, you don’t want to miss that! You would have a hard time to get
their attention at any other time.
So be prepared! Think hard about the important questions (tip: usually the
ones that hurt) and look at the mentors’ bios, articles, and anything else you
can dig up. If there’s a fit, that’s a win! Don’t take it lightly, this is
probably harder than preparing your pitch. You’re probably thinking you only
have one chance to make a good first impression with your pitch, while you
can’t shame yourself too badly by being underprepared for the mentoring
sessions. You’re right… but I’m convinced it is much more fruitful to
concentrate on getting answers and advice that could mean success over failure
for your company (a passable pitch may not be enough to get a Seedcamp
investment but good advice might reap untold rewards). Convinced? Have a look
at Andreas Klinger excellent post to get on track!
In our case, Julien did most of the work preparing for mentoring while I
concentrated on the pitch. Could we have done more? Probably. Should we have
done more? Yes. One month after the event, I think we put a good level of
effort into the pitch preparation, but we should have taken some more time on
the mentoring preparation. Honestly, I think we were good, with a clear list
of questions and we were ready to shut up and listen. But we could have
researched the mentors more thoroughly, especially the ones not on our
schedule.
D Day
Your pitch is ready, you’ve got all mentors covered, you slept 8
6 4 as many hours as you could… let’s do this! First,
get up early. Arrive at least 30 minutes before the start of the event. Then
you have time to relax, get friendly with other teams and actually take the
opportunity to speak with a few mentors before the event.
After a relatively short presentation by the Seedcamp team, it will be time
for the pitches! 20 of them, 3 minutes each. Attention tends to drift, which
is why your pitch has to be captivating. Now is your chance to shine and put
all your practice to the test! We were lucky to go first as we were sorted in
alphabetical order. Other participants thought that was unlucky but I was
thankful! I had an opportunity to grab the audience’s attention and there was
no time for stress to build up in anticipation before our turn… and
everything went all right! It was actually one of my best performances, much
better than during training the previous day.
One thing we could have improved was leveraging the pitch for communication.
There are two things you can easily do - take some photos or a video, and
tweet about your experience! Also, always have your twitter handle visible on
the slides. You may think it is enough to put it on the first and last slides
but what if someone watching wants to tweet during your pitch? Make it easy
for them!
Time for Mentoring
OK, so you are prepared for the mentoring and have researched all the mentors?
Some good ones are certainly not in your schedule so go and meet them during
the breaks! And either ask them to participate in your open sessions (mentors
are free to pick the teams they want for the last two sessions) or directly
ask them the questions that trouble you. Don’t expect them to remember
everything you said during your pitch (they just saw 20 of them!) so get a
short intro ready. It is also better to have a quick demo instead of too many
words.
You’re now up for 5 or 6 sessions of intense discussion with mentors. Andreas
provides excellent advice on the pitfalls and potential
benefits of these sessions. Don’t forget, mentors are there to help you, they
won’t attack you. Don’t try to convice them you’re right, just listen what
they have to say. Don’t lose time explaining every aspect of your startup,
instead ask specific questions about their experience. And don’t be shy to ask
for introductions. Either they will or they won’t, but it doesn’t hurt to ask!
Of course nothing is ever perfect. All mentors are not equal and some of them
may not even show up to your scheduled session (don’t blame them, they usually
have a hectic schedule and your startup may not have an activity they relate
to). Anyway, you don’t need to speak with all of them. It is much better to
enjoy profound and fruitful discussions with a few.
Followups
The day concludes with a party - in our case at a nice wine bar. As you can
guess, every team was quite exhausted and didn’t stay late. A handful would be
invited back the next day to discuss potential participation in the program.
The selection process is a little obscure, with no clue provided as to their
criteria. This is a bit frustrating as I would have appreciated to know why
they didn’t select us.
Keep in mind that mentors will have been approached by many people and may
forget the intro they promised you. Connect with them, thank them for their
precious advice, and kindly remind them of the introductions they promised.
And if you had a really good discussion with some of them, see if they would
be happy to continue a more regular mentorship role.
Takeaways
To get the best out of your Seedcamp final, you should invest a lot of time in
preparation. Don’t bet everything on being accepted, the pitch day and
mentoring alone is definitely worth your effort. The preparation itself helped
us to focus on key questions and strategic decisions. We then had a priceless
opportunity to test our ideas with experts in many domains and to ask them
focused questions. That was like 6 months worth of mentorship in one day and
it profoundly affected our strategy for 2013! The event also boosted our
network - we contacted many people directly after the event and a few have
even become regular mentors.
The Seedcamp team is amazing but there is some room for improvement. We got
excellent feedback on our pitch during the training, but unfortunately, it
was lacking after the actual event. We were forwarded a few very nice comments
from mentors, but that was it. While we had the opportunity to discuss
directly with mentors, I would have loved to have some feedback from the
Seedcamp team. I understand they do not want to encourage debate over their
selection decisions, but understanding their reasoning would certainly be
useful.
From listening to other participants about their experience, be aware that if
you are selected for investment, the paperwork is time-consuming! Do not plan
too many developments for your startup or you may be disappointed by the poor
progress you’ll make during that time. And don’t forget that the Seedcamp US
trip is early the following year and that is something to prepare for too!
Another important thing we overlooked when applying is the need to
(re)incorporate your company in the UK. This is not such a big deal in the
first year as you will have help from Seedcamp but what about afterwards,
especially if you operate from your home country? Each country’s legislation
is highly specific and you may have some headaches in store. Don’t forget to
prepare for this before the end of the Seedcamp program.
In conclusion, Seedcamp Paris lived up to its reputation. Asked if we would do
it again, we would certainly answer yes! And I sincerely encourage other
startups to give it a go!
10 Jan 2013
When we started Algolia Development for Android, binary size optimization was
not one of our main concerns. In fact we even started to develop in JAVA
before switching to C/C++ for reasons of performance.
We were reminded of the importance of binary size by Cyril
Mottier who informed us that it would be
difficult to integrate our lib in AVelov Android Application because its
size. AVelov is 638KB and Algolia was 850KB, which would mean that AVelov
would more than double in size with Algolia Search embedded.
To address this problem we managed to reduce Algolia binary size from 850KB to
307KB. In this post we share how we did it.
Do not use Exceptions and RTTI
We actually do not use exceptions in our native lib, but for the sake of
completeness, I’ll cover this point too.
C++ exceptions and RTTI are disabled by default but you can enable them via
APP_CPPFLAGS in your Application.mk file and use a compatible STL, for
example:
APP_CPPFLAGS += -fexceptions -frtti
APP_STL := stlport_shared
Whilst using exceptions and RTTI can help you to use existing code, it will
obviously increase your binary size. If you have a way to remove them, go for
it! Actually, there’s another reason to avoid using C++ exceptions: their
support is still far from perfect. For example if was impossible for us to
catch a C++ exception and launch a Java exception in JNI. The following code
results in a crash (will probably be fixed in a future release of the Android
NDK toolchain):
try {
...
} catch (std::exception& e) {
env->ThrowNew(env->FindClass("java/lang/Exception"), "Error occured");
}
Do not use iostream
When starting to investigate our library size following Cyril’s feedback, we
discovered that Algolia binaries had vastly increased in size since our last
release (from 850KB to 1.35MB)! We first suspected the Android NDK toolchain
since we upgraded it and tested different toolchains, but we only observed
minor changes.
By dichotomy search in our commits, we discovered that a single line of code
was responsible for the inflation:
std::cerr << .... << std::endl;
As incredible as it may sound, using iostream increases a lot the binary size.
Our tests shown that it adds a least 300KB per architecture! You must be very
careful with iostream and prefer to use __android_log_print method:
#include <android/log.h>
#define APPNAME "MyApp"
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "The value of 1 + 1 is %d", 1+1);
Make sure you also link against the logging library, in your Android.mk file:
Use -fvisibility=hidden
An efficient way to reduce binary size is to use the visibility
feature of gcc. This feature lets you
control which functions will be exported in the symbols table. Hopefully, JNI
comes with a JNIEXPORT macro that flags JNI functions as public. You just
have to check that all functions used by JNI are prefixed by JNIEXPORT, like
this one:
JNIEXPORT void JNICALL Java_ClassName_MethodName
(JNIEnv *env, jobject obj, jstring javaString)
Then you have just to add -fvisibility=hidden for C and C++ files in
Android.mk file:
LOCAL_CPPFLAGS += -fvisibility=hidden
LOCAL_CFLAGS += -fvisibility=hidden
In our case the binaries were down to 809KB (-5%) but remember the gains may
be very different for your project. Make your own measures!
Discard Unused Functions with gc-sections
Another interesting approach is to remove unused code in the binary. It can
drastically reduce its size if for example part of your code is only used for
tests.
To enable this feature, you just have to change the C and C++ compilation
flags and the linker flags in Android.mk:
LOCAL_CPPFLAGS += -ffunction-sections -fdata-sections
LOCAL_CFLAGS += -ffunction-sections -fdata-sections
LOCAL_LDFLAGS += -Wl,--gc-sections
Of course you can combine this feature with the visibility one:
LOCAL_CPPFLAGS += -ffunction-sections -fdata-sections -fvisibility=hidden
LOCAL_CPPFLAGS += -ffunction-sections -fdata-sections -fvisibility=hidden
LOCAL_CFLAGS += -ffunction-sections -fdata-sections LOCAL_LDFLAGS += -Wl,--gc-sections
This optim only got us a 1% gain, but once combined with the previous
visibility one, we were down to 691KB (-18.7%).
Remove Duplicated Code
You can remove duplicated code with the –icf=safe option of the linker. Be
careful, this option will probably remove your code inlining, you must check
that this flag does not impact performance.
This option is not yet available on the mips architecture so you need to add
an architecture check in Android.mk:
ifneq ($(TARGET_ARCH),mips)
LOCAL_LDFLAGS += -Wl,--icf=safe
endif
And if you want to combine this option with gc-sections:
ifeq ($(TARGET_ARCH),mips)
LOCAL_LDFLAGS += -Wl,--gc-sections
else
LOCAL_LDFLAGS += -Wl,--gc-sections,--icf=safe
endif
We actually only obtained a 0.8% gain in size with this one. All previous
optimizations combined, we were now at 687KB (-19.2%).
If you want to go even further, you can change the default compilation flags
of the toolchain. Flags are not identical accross architectures, for example:
- inline-limit is set to 64 for arm and set to 300 for x86 and mips
- Optimization flag is set to -Os (optimize for size) for arm and set to -O2 (optimize for performance) for x86 and mips
As arm is used by the large majority of devices, we have applied arm settings
for other architectures. Here is the patch we applied on the toolchain
(version r8d):
--- android-ndk-r8d/toolchains/mipsel-linux-android-4.6/setup.mk
+++ android-ndk-r8d.new/toolchains/mipsel-linux-android-4.6/setup.mk
@@ -41,12 +41,12 @@
TARGET_C_INCLUDES :=
$(SYSROOT)/usr/include
-TARGET_mips_release_CFLAGS := -O2
+TARGET_mips_release_CFLAGS := -Os
-g
-DNDEBUG
-fomit-frame-pointer
-funswitch-loops
- -finline-limit=300
+ -finline-limit=64
TARGET_mips_debug_CFLAGS := -O0
-g
--- android-ndk-r8d/toolchains/x86-4.6/setup.mk
+++ android-ndk-r8d.new/toolchains/x86-4.6/setup.mk
@@ -39,13 +39,13 @@
TARGET_CFLAGS += -fstack-protector
-TARGET_x86_release_CFLAGS := -O2
+TARGET_x86_release_CFLAGS := -Os
-g
-DNDEBUG
-fomit-frame-pointer
-fstrict-aliasing
-funswitch-loops
- -finline-limit=300
+ -finline-limit=64
# When building for debug, compile everything as x86.
TARGET_x86_debug_CFLAGS := $(TARGET_x86_release_CFLAGS)
We were good for a 8.5% gain with these new flags. Once combined with previous
optimizations, we were now at 613KB (-27.9%).
Limit the Number of Architectures
Our final suggestion is to limit the number of architectures. Supporting
armeabi-v7a is mandory for performance if you have a lot of floating point
computation, but armeabi will provide a similar result if you do not need a
FPU. As for mips processors… well they just are not in use on the market
today.
And if binary size is really important to you, you can just limit your support
to armeabi and x86 architectures in Application.mk:
Obviously, this optim was the killer one. Dropping two out of four
architectures halved the binaries size. Overall we obtained a size of 307KB, a
64% gain from the initial 850KB (not counting the bump at 1.35MB due to
iostream).
Conclusion
I hope this post will help you to reduce the size of your native libraries on
Android since default flags are far from optimal. Don’t expect to obtain the
same size reductions, they will highly depend on your specific usage. And if
you know other methods to reduce binary size, please share in the comments!
28 Dec 2012
I’ve been convinced for a long time that simplicity is the most important
property of a product. Long-gone are the 90s when a product was admired for
its complexity. But I am also convinced that this is the most complex property
to achieve and maintain as time passes by.
A good example of an over-complex product is Atlassian JIRA, a bug tracker
that also do scrum management and plenty of other things via dozens of
plugins. It’s basically a toolbox to create the bug tracker adapted to your
company.
In my previous job, I faced an uncomfortable situation with JIRA because of
its complexity. We used it for bug tracking and scrum management and I tried
to upgrade our old version to the latest one. After some long hours to upgrade
our setup on a test server, I finally got the latest version working but most
of our installed plugins were not available anymore because the authors did
not port their plugins to the new plugin API. Of course each plugin was there
for a reason and I was in a tricky situation: keep the old version with
security issues or upgrade to a new version without our plugins.
But it was far more vicious: There were about 10 versions between our old
version and the latest one, and I didn’t find any of these versions working
with our set of plugins! In the end, we were forced to keep our old version.
Atlassian forgot the most important lesson, even with a toolbox: simplicity!
This is probably more expensive for them to keep plugin backward
compatibility, but I would prefer for them to not have any plugin rather than
breaking compatibility at each release. The final system is too complex to be
maintainable and our final decision was to stop paying for JIRA support since
we were blocked with an old release. It is even bad for their business.
You should be focused on simplicity for your users even it this results in
more complexity for you (like maintaining backward compatibility)! As this
post is strongly related to backward compatibility of API, I encourage you to
reread this famous post of Jeol Spolsky: How microsoft lost the API
war.
21 Dec 2012
One of the worst user experiences I have ever had with software was with the
Sony PS3. I kind of liked this product; I found the user interface very nice
and well organized… but they were much too aggressive about upgrades! They
simply blocked features until the upgrade was done!
A few weeks ago I wanted to watch a VOD movie with my wife. I launched the
Playstation Store that asked me to upgrade the OS to the latest version.
That’s 45 minutes before being able to access the Playstation again! But
wait! Once the new OS was installed, I tried to launch the Playstation Store
again… This time, it was the Playstation Application that was not up to date
!
In total it took me over 1 hour to do upgrades and guess what, at the end
it was just too late to watch the movie!
Generally, frequent upgrades are good for your users, and I am sure there are
plenty of bug fixes/improvments in the lastest version. But Sony has just made
the wrong choice in blocking features until the upgrade is done. This is just
plain frustrating for users! On the contrary, Android and iOS propose an
upgrade that you can apply when you want. Best of all, they download in the
background.
It may sound evident, but it is very important to ensure your users will
always be able able to keep control over their products. You should never
force them to do something they do not want to, like Sony did with the PS3.
20 Dec 2012
You may have been expecting Windows Phone 8 as our next platform of choice,
but we preferred to go Windows 8 first! With more than 40M sold in a month,
let’s say it’s a slightly more interesting market for now.
Windows 8: Our First Move to the Desktop
Yes, desktop apps are not as dead as many people think, especially now that
both Mac OSX and Windows come with their app stores. Sure, Windows is now
running on tablets - and we also support them - but it will take time before
they surpass desktops.
What’s more, the new Windows 8 Metro Modern UI includes a charm bar
with search and autocompletion as the number one feature. Microsoft actually
provides an interface to ease application integration in the charm search
bar… but no library to help you implement it. No problem, here comes Algolia
Search for Windows 8!
Awesome Features for Your Apps
The core technology is exactly the same as the one in our iOS and Android
versions. That means you’ll get exactly the same exceptional performance…
well probably even better depending of the hardware you’re running on. You’ll
also get instant visual feedback, typo-tolerance and multiple attributes
support! See all the features on our
website.
Easy to Integrate in your Language of Choice
Check out the dedicated tutorials! The
Algolia Search library has been designed to work directly on the platform.
That means you can use it in whatever language you prefer, be it JS or one of
the .Net choices (C#, VB, C++). The tutorials are available in both JS and in
C#.
Moreover it is fully compatible with Microsoft Search Contracts. It just
became child’s play to integrate Search in your Windows app!
Hey Microsoft, There are a Couple of Features You Could Improve
Windows 8 is clearly a step in the right direction, but we encountered some
problems we didn’t expect!
First is the multi-arch support. While it’s just straightforward with iOS or
Android (out of the JNI part…), using a native lib forces the developer to
chose an architecture on Windows! Fortunately, Visual Studio Package Generator
handles that correctly and proposes you to select all architectures for your
final export. But well… we’d have preferred it plain and simple.
Our second deception is a bit more problematic as it prevents one of our very
nice features: typo-tolerant highlighting during autocompletion. It starts
with best of intentions from Microsoft. To remove the burden of implementing
highlight for autocompletion on developers, Windows 8 handles it directly. The
only problem is that it cannot be replaced by our own :( So you can obtain
hits even if your query contains typos, but hits containing text different
from the query won’t be highlighted.
We hope to be able to change this behaviour in the future. In the meantime,
we’re impatient to get your feedback on this beta!
Register for your Windows 8 version of Algolia
Search now!