Rachels Lab Notes

Game Development as seen through the Blum Filter

The hidden cost of C++

with 60 comments

As a game developer, I’m concerned with performance. Yes, we’re living in next-gen land, and there’s a lot of performance – but then somebody comes along and squeezes every last drop out of a platform you develop for, and you better do that too.

As such, I’m occasionally involved in discussions about the merits of using C++. As such, one topic that comes up in every single discussion is the ‘hidden cost’ of using C++. And the reply is inevitably “There’s no such thing! It’s all in the source code!”

Well, yes, it is. But let me explain what I mean by it.

In C, if I have a line of code like this:

  1. a = func(b,c);

I can take a rough guess at the cost of the function by the name of it. The only other part I need to have a mental model of the performance is the overhead involved. And in C, the cost of a function call is pretty fixed. The only ‘surprise’ that can happen is that it’s inline and thus faster than you expected.

Not so in C++. Is it a function call, a member function call, or is it an anonymous constructor? Are b and c implicitly invoking copy constructors for other classes as part of type coercion? Is that a normal assignment, or an assignment operator? Is there a cast operator involved?

And once I have answered those questions, I have to look at all the classes involved. If they have a non-empty destructor, cost is added. Should those destructors be virtual, more cost is added. Virtual cast operators? Add some more.

As the end result, your overhead can grow dramatically. Especially those virtual calls are quite costly. The total runtime of a loop can easily vary by 10x or more based on those parameters.

Of course, they are not really hidden – if I look at the source code, I can easily see them. The real hidden cost is that now, instead of looking at one piece of source – the function itself – I need to look at up to four different classes. Add possible ancestors to find out if a call is virtual.

That is the hidden cost. The mental model for a simple function call became incredibly large and complex, and every function call is potentially as complex. Which makes reasoning about performance a rather hard thing to do.

Worse, it makes profiling harder than necessary. All the type coercions that happen at the API level will show up as separate functions, not attributed to the callee, but the caller.

All that translates ultimately into either worse performance or longer development time. Neither one is something you like to hear about.

Written by groby

October 20th, 2009 at 7:04 am

Posted in Language

60 Responses to 'The hidden cost of C++'

Subscribe to comments with RSS or TrackBack to 'The hidden cost of C++'.

  1. That’s why I always look at the disassembly, so I know if it’s just a “CALL” or “BL” instruction instead of pages of code generated by one line.

    Rebecca Heineman

    20 Oct 09 at 8:49 am

  2. I understand and agree with all your points, but I think the important question that all this raises is: if not C++, then what?

    Basu

    20 Oct 09 at 8:58 am

  3. Nobody said that C++ was meant to be easy considering the really wide application scenarios. Yes, it is a complicated language. Yes you remain a newbie for centuries. Yes feature X it has, sucks because language Y does it better for dummies.

    But asides that, there is absolutely nothing that can substitute it right now when considering the complete package it offers. Unless you want your game to run on pathetic VMs.

    ginee

    20 Oct 09 at 9:22 am

  4. Social comments and analytics for this post…

    This post was mentioned on Hackernews by JoeAltmaier: I fixed a single line of code that drove our embedded processor to 50% cpu – it called 5 ctor/dtors. Changing it to a ref arg with a ref return, and dropped to under 10%. And yes, class defs had to …

  5. The reason for the overhead is to simplify creating larger games. So the real question then becomes a matter of deciding whether game performance is more crucial than time to market.

    For some games, performance isn’t a big deal. For other games, performance is key. As long as you’re aware of the trade-offs like you’re describing, than you can make an informed decision. Just picking C++ because it’s easier doesn’t necessarily mean you’ll get better performance because it’s like C.

    Steph

    20 Oct 09 at 9:33 am

  6. @Rebecca: In theory a good idea, but it’s kind of hard to scale to 2.5 MLOC of code ;)

    @Basu: That’s an excellent question, and one I’m pondering at the moment. My current conservative suggestion is: Kernel in C, driven by a script language on top. Long term, I think the best approach is multi-language, depending on the domain you tackle.

    @ginee: It’s not about C++ being ‘easy’. I write code in assembly, Python, Haskell, Erlang,… so I think I can deal with ‘not easy’. It’s about the horrible cost creating a mental model of your program creates.

    @steph: I’d argue that C++ doesn’t actually simplify, compared to C+scripting language. And if you take a look at e.g. Uncharted2, you’ll see that performance is very important if you want to keep competing in that market.

    For smaller games, there are certainly better choices. C# for XBLA comes to mind. Heck, I’d argue ObjectiveC on the iPhone is a better choice than C++. (I really don’t think it’s a good language at all. It’s a total hodgepodge of features and feels like somebody glommed everything together that was ever considered ‘cool’.)

    labmistress

    20 Oct 09 at 9:46 am

  7. C++ is a higher level language. You are comparing a powerful instruction with a simple one. You should compare the complexity of code written in the two languages which performs the same function. As with all languages: horses for courses.

    Ant

    20 Oct 09 at 10:23 am

  8. “Which makes reasoning about performance a rather hard thing to do.”

    Even in C, reasoning about performance is quite hard. If you’re serious about performance, you’ll have to measure. When using e.g. a profiler, you’ll clearly see where the cycles are burned. No need to make good guesses or, as you put it, to “reason” about the code.

    Volker Grabsch

    20 Oct 09 at 10:38 am

  9. Whoops, forget my last comment. I overlooked your paragraph where you stated your problems with profilers and C++.

    Volker Grabsch

    20 Oct 09 at 10:41 am

  10. ….is it a function call, a member call, or is it an anonymous constructor

    Ultimately these are all just function calls and so have exactly the same performance costs.

    ….Are b and c implicitly invoking copy constructors for other classes as part of type coercion?

    You can declare copy constructors as private for objects you don’t want to copy. Add the ‘explicit’ keyword to all constructors that can be called with a single argument so they cannot have implicit conversions to them. Never declare conversion operators.

    After that it becomes almost impossible to have a conversion between any two class types.

    ….is that a normal assignment, or an assignment operator

    Declare your assignment operators as private. Add an “assign” member to all your classes so that when you do want assignment you have to explicitly call it.

    ….Is there a cast operator involved?

    If you’re referring to a function style cast then it can only have 1 argument, so “func(b,c)” cannot be a function style cast. To catch the single argument case, you can make your constructors private and add a “create” member so casts will not be possible on any of your types.

    ….if they have a non empty destructor…

    The non-empty destructor is apparently doing something that needs doing, so it is saving you from having to do some cleanup manually. I can see the point you’re trying to make, but what’s better: Forgetting to do important clean up? (eg. free memory, free GUI object) or automatically having the cleanup take place that you would have had to do anyway?

    ….should they be virtual

    If you have a virtual dtor, then it’s because you have a hierarchy of objects and you want the convenience of not having to manually work out what class you really have and so freeing up the correct amount of memory. You can of course do this as you would in C. Leave all destructors empty and non virtual. Add a deleteHierarchyX call. Each class sets a “kind” member, you switch on that member, “static_cast” the object and then delete the appropriate object type.

    …. virtual cast operators?

    If you’re referring to dynamic_cast, then at least its pretty clear that its being called! :)

    ….The total runtime of a loop can easily vary by 10x….

    I would love to see such a loop! Of course, the C and C++ code have to be doing exactly the same things!

    If you’ve got a virtual function call, then you have to match that on the C side with equivalent functionality, eg. an array of function pointers. It’s not really correct to take a virtual function call and compare it to a non virtual call and say: “Hey look it’s slower”.

    ….That is the hidden cost. The mental model for a simple function call became incredibly large and complex, and every function call is potentially as complex. Which makes reasoning about performance a rather hard thing to do.”

    I hope I’ve highlighted a little how you can remove a lot of the “implicitness” with C++. One of the reasons that I really enjoy using C++ is that it is so flexible. It can be used by both the “I don’t care about performance, I only want convenience” camp as well as the “I want cutting edge performance” side.

    In your case, it will require more effort, however, as you’ve said, you want to be able to see exactly where you’re paying for “conversions” to take place.

    Incendentally, a lot of the general performance myths re C++ were tackled in the “TR on C++ Performance” which was completed by the people on the C++ Standard Committee. (http://www.open-std.org/jtc1/sc22/WG21/docs/TR18015.pdf)

    Richard

    20 Oct 09 at 11:59 am

  11. “Which makes reasoning about performance a rather hard thing to do.”

    Reasoning about performance is always a rather hard thing to do. C++’s complexity isn’t the culprit, C wouldn’t be the culprit either. Predicting what the CPU will do with your binary is extremely difficult and many times unintuitive. Reasoning with only your (and everyone else on your team’s) brain is the problem. This is why we have (and should use) profiling tools. Regardless of the language, if your profiler is telling you that you’re spending 90% of your time in a single function, you’ll spend an equal amount of time squeezing all of the performance out of it as necessary.

    I believe that the hidden cost of C++ isn’t in being difficult to optimize, it’s that it’s too easy to be distracted by the thoughts of performance while one is writing straightforward code. This leads to convoluted code by programmers thinking that they’re being clever (premature optimization) leading to good old fashioned code smell.

    Easy-to-read code is easy-to-debug. Easy-to-debug code gets completed faster. Faster completion will give you more time to then optimize the really important parts.

    Sufian

    20 Oct 09 at 12:43 pm

  12. Isn’t that the cost of higher levels of abstraction. Essentially you are choosing a particular language because it’s balance of performance and abstraction meet your requirements perfectly. It’s not fair to complain about the “hidden” overhead of c++ function call vs. c. It’s like complaining that that your web server written in asm is so much faster than the one in python.

    Cashua

    20 Oct 09 at 12:59 pm

  13. I’ve found my ambivalence about C++ has grown over the years. But as an above commenter pointed out, with 2.5 MLOC, going back to C really isn’t an option.

    I think the biggest problem is C++ is a systems language that was sold as an application language, too. It is a horrible applications language. These days I much prefer to work in something like C# at the application level, where you get really great tools and a nice language.

    I still think C++ is a better choice for systems-level programming than C, because even with a layered approach of all your higher level game code in something like C# and your heavy lifting in C++, that heavy lifting layer is complicated enough to a point where C’s lack of abstraction facilities brings you down. Systems programmers tend to be fully aware of the performance pitfalls of C++ and avoid them.

    If I were to architect an engine from scratch, I’d try an approach where the game is written in C# and talks to C++ systems that do the heavy stuff. Of course, this would require fully supported, professional-level tools, which don’t really exist on the consoles yet (XNA is nice but I really just want a JIT, and I’ll make my own framework, thank you).

    Also, I’m not entirely sure we’re on the part of the performance curve in games where we can make this jump. While I’ve worked on PC games in the past that did exactly the above (replace C# with Java), those had much less intensive performance constraints. Using garbage collectors designed for desktop environments on a console isn’t going to perform very well — IMHO automatic memory management in memory-constricted environments is still somewhat of an unsolved problem. Most of the garbage collectors I’ve seen on console do not impress me with their capabilities, and still rely on a mark step that takes a frame or more to complete.

    As far as the higher level language, you could take your pick – C#, Java, haskell, python, erlang, lua, whatever is your personal preference. I think something with a JIT would be preferable.

    vince

    20 Oct 09 at 4:45 pm

  14. C++ is a bad language but the fact is that the OOP support and libraries available for the language speed up development considerably. In C you have to recreate stuff like Boost from scratch. Working with objects is just conceptually closer to the world in which we live but there is some overhead to the vtables in class hierarchies and what not. I think a good potential alternative to C++ is the D programming language but its just not mature enough yet. BTW I really wish more game development blogs would share more code examples; I can’t hardly find any examples from pros in the trenches. I guess there must be strict NDA’s in place. Sigh

    terry

    20 Oct 09 at 6:46 pm

  15. @ant, @cashua:My issue is not with the fact that C++ has a higher cost. My issue is that the cost of a C++ construct is not predictable without parsing a lot of code. The unpredictability makes it hard to keep an eye on performance while coding.

    @Sufian: At no point did I advocate reasoning only. But cost of code is to some extent predictable – CPUs are not quite as mysterious as you make them out to be. Can I predict to the cycle level? Of course not – but I can venture a decent guess. Having a 10x deviation for the same construct based on non-callsite code makes it entirely impossible.

    labmistress

    20 Oct 09 at 9:04 pm

  16. @Richard: Thanks for taking the time to explain all that. I am certainly aware of this, but the point is that I need to know what happens with all types involved, not only with the function in question. Of course I can avoid this overhead – unless somebody else introduces it. (Worst case, long after the fact)

    And yes, I’m aware of the performance TR, too. I do in fact have the (dubious) pleasure of checking on the status of C++ quite regularly. C++ is the majority of my work, after all.

    labmistress

    20 Oct 09 at 9:10 pm

  17. @Vince: Interesting that you still want to stick with C++, given one of your recent posts on overrated features in C++ ;)

    But yes, it is quite possible that you really need the abstraction features. I’m not arguing for a complete abandonment of the language. (Only because I can’t offer a replacement, though!)

    But I’m tired of the C++ apologists saying that there is no hidden cost. Writing proper C++ is hard work, as you’re well aware – it is time people acknowledge that and think a little bit harder where it can and cannot be applied, and if really the entire team needs C++.

    I also agree that – unfortunately – VMs are not quite there yet. (My bet is on LLVM and its JIT driving tool creation. A lot of research is attaching itself to LLVM)

    And finally, as for the higher level language – as you, I really don’t have too strong of a preference. But one of the issues I consider mandatory is hot reloading – something most languages neglect. (The only one I’m aware of that does it well is Erlang). And just because I’m greedy, a REPL/interpretative mode of the language would be very welcome too. I.e. fix interactively until you get it right, then compile for speedup.

    labmistress

    20 Oct 09 at 9:18 pm

  18. @Terry: Yes, sharing code from our work would be a rather significant breach of professional ethics. So don’t expect anything in that regard any time soon.

    That being said, I am constantly lobbying to open-source some of our code, but it’s an uphill battle. (And requires making a business case, which is about as foreign as Martian to me ;)

    As for languages: I keep looking at D, but it’s not bringing enough advantages to the table to justify switching over. Even if all its issues were resolved. Another fairly good (but not good enough to switch) language would be ObjectiveC, especially with good libraries. (Yes, I’m an Apple fangirl – what can I say…)

    labmistress

    20 Oct 09 at 9:24 pm

  19. @labmistress:

    … but the point is that I need to know what happens with all types involved, not only with the function in question. Of course I can avoid this overhead – unless somebody else introduces it. (Worst case, long after the fact)

    In the same way that you need to make sure nobody calls some expensive OS call in the code, you need to enforce a strict class style. But once you do that you can just look at the function body in question.

    No language is going to protect you from people who don’t know what they’re doing. Are there not constructs/calls in C that are avoided for performance reasons? All these things have to be learned.

    You could possibly argue that C++ has a steeper learning code if you want to use it in a performance based environment. This would lead to an interesting discussion about the “possible” long term benefit of using a strict C++ vs sticking with C.

    I remember talking with some people from a large company that needed real time image processing.

    One function ran different filters over a large bitmap. Each filter would operate over some sub matrix of the image, eg. 4×4 or 3×3. The original version of the code was a function that contained a very large switch statement for the different filter kinds and lots of code around to handle the different matrix sizes etc. The code was getting too hard to maintain so they decided to simplify it.

    The initial change passed in a callback function pointer. That function then handled the different filtering. This was much slower than the previous version and was rejeceted as a solution.

    Some of the C++ team suggested that they might be able to do it better. Their solution used a function template with functor objects for the filtering step. I cannot remember the actual performance improvements but not only was their verseion faster than the function pointer version, it was faster than the original pure C with switch statement version!

    The problem with the original version is that it had lots of special cases for the different filter kinds. With the function template approach, each instantiated function only handled the code it needed for its filter. The result was that certain filters ran dramatically faster.

    The only real way to achieve something like this in C would be to define all this in a MACRO! And debugging that would be fun! :)

    Richard

    21 Oct 09 at 5:31 am

  20. @Richard: I’m not arguing you can’t write high-performing code in C++. I’m arguing that it’s harder to do so without a lot of knowledge of C++ – i.e. the “learning curve” argument.

    And even then, the occasional mistake can cost you dearly, and is harder to find in the profiler. (And coding standards don’t save you from mistakes, unfortunately. C++ coding standards – by virtue of language complexity – are large beasts.)

    And yes, I’ve heard the filter/matrix library function template argument any number of times – but there’s a lot of code that’s not that easily rolled up, and still has performance problems.

    I’ll readily admit C++ can be a powerful tool – but IMHO it’s too complex to use over an entire large code base.

    labmistress

    21 Oct 09 at 6:23 am

  21. I stick with C++ despite its flaws because it is the only practical choice for a systems level language. C lacks abstraction facilities that really are helpful, and really, some of the worst things in C++ are due to C compatibility (macros, implicit conversions, garbled syntax in places).

    There is a huge amount of middleware for games available in C++, a huge developer ecosystem, and pretty good tools given how complicated parsing the language is. I’d have to have a pretty good reason to throw those away, and the fact that implicit conversions are a bad idea is not a good enough reason.

    Of course, I don’t begrudge you wanting to make a different choice. In fact, I encourage it. While I’m sure there are still a handful of straight C game shops out there, maybe you should do an experiment and write a small game strictly in C? And I don’t mean a C-like subset of C++ (that’s cheating), I mean C99 or whatever the latest standard is.

    While it won’t be quite a fair comparison since the code bases we deal with are considerably larger these days, if nothing else it’d make for some good blog posts.

    vince

    21 Oct 09 at 7:48 am

  22. Just jumping in here. I use C++ at work (games) everyday, and have over the years begun to get bored with its complexity. When I’m in the “spot” I can write great performant code without issues, but when on slow day…

    Anyways unfortunately neither D or C# are really up to the task yet. But yes you can use C. Here in Japan there are still plenty of C shops, however most work on smaller portable games, but I can say that Virtual Fighter 5 was written in C, not C++. That was epic. Because the glue code was C.

    In my spare time, I have actually been writting game components in straight C, and it’s trivial to write physics, graphics, IO, network, persistency, etc. in plain C. The real issue is the glue (gameplay) code. Writting glue code in C is crazy, but writting glue code in C++ is about as cumbersome as C is crazy, so I’ve been using Lua (Jit) for glue, which works great when combined with a good memory allocator.

    Anyways I’m still keeping my hopes that something simpler and more concise comes around to replace our reliance C++ within the next 5 years!

    Robert

    21 Oct 09 at 9:27 am

  23. @vince: Oh, we’re sticking with C++ for the time being, too. Which is understandable – I wouldn’t gamble a $25 million project on some gal’s hunch that something else could work better ;)

    Thankfully, here I can take a more exploratory stance. And by simply posting my (moderate, I think) objections to C++ and having a fantastic follow-up discussion, I get to clarify my thoughts looking for the elusive ‘better choice’

    Middleware could certainly be dealt with via C++ ABI compatibility/FFI. Tools are an issue – the only languages that can compete on a tools level right now are C# and Java. As I said, my hope is on LLVM changing this.

    Doing this experiment would be tempting. Just need to find the time… In case it does happen, it would in all likelihood be developed in the HLL first, dropping down to the lower level if performance indicates it’s necessary. Probably in a restricted VM, just so I actually feel some pressure to drop down – small games are not exactly performance hogs.

    The Löve code-base also might be interesting, since it is (IIRC) written entirely in C.

    groby

    21 Oct 09 at 9:35 am

  24. @Robert: It’s interesting that it’s a fighting game that was written in C – another C holdout I got to work with was also a fighting game team. I’d figure that the absolute need to reach 60fps makes them reluctant to move on – although they did move on, at some point.

    And I don’t think AAA games are abandoning C++ within the next 5 years. We might – possibly – see VMs making inroads for scripting purposes, but even that is doubtful given the inertia of our industry.

    groby

    21 Oct 09 at 9:38 am

  25. @labmistress

    Quoting you: “It’s not about C++ being ‘easy’. I write code in assembly, Python, Haskell, Erlang,… so I think I can deal with ‘not easy’. It’s about the horrible cost creating a mental model of your program creates.”

    I have a feeling that you are then dealing with improperly trained programmers. Nobody serious in the industry has problems with a complicated mental model. Complicated != crap, complicated = complicated. And you can argue about writing in language X that are “complicated” all you want.

    These languages however ARE designed to be extremely high abstraction layers that take away the cost of dealing with the hardware where you have to. And at the high level, properly done C++ puts to shame everybody right now.

    As for the rest, as a contributor to very well known compilers out there, I know what I am talking about. Using C++ has more to do with multilevel access than anything else. Speed is a welcomed side – effect when done right, but then again, you have to actually know how to program in C++, which takes several years to master. It is not your “for dummies” language. It is meant to be used where the others fail and that should kind of suggest of why you don’t have a worthy successor yet.

    This is not a contest of “look I can write code in a turing tarpit, does that make me look smart?”. So far, you have no reak immediate alternative to C++ despite the best of intentions. When I will be having a language that supports a system similar to templates and what actually can be done with it, we will talk about it. So far, Haskell’s “Template Haskell” has proved to be worthless. But guess what … it tries to do what C++ does!

    Use what you have to, when you have to.

    Just my 2c.

    ginee

    21 Oct 09 at 9:55 am

  26. [...] my post on the hidden cost of C++, Vince suggested I go write a small game in C, see how I like [...]

  27. [...] hidden cost of C++ or Defective [...]

  28. Programming is hard. In any language. C is terrible.

    a = func(b,c)

    In any large C project I’ve seen func() will call f(), g(), h(), m() which in turn call F(), G(), L(), Q(). Now Q() locks a mutex. L() opens a file for logging. G() uses a linked list structure written by some co-op two years ago that is not thread safe (but has worked fine till today). F() uses some obscure macros and has security issues due to the use of strncpy or sprintf.

    Now, what is the cost of func(b, c)?

    C++ is far for perfect. In fact it is terrible just like C. But it has some solutions for some of the issues in C. It allows OOP (which a lot of C programs end up emulating in awkward ways). It has good robust libraries (stl, boost) and it interfaces in a nicer way to existing object oriented frameworks. It is fast.

    A lot of people hate C++ and usually pick up on some esoteric feature. A lot of people don’t get it. A lot of C programmers forget how long it took them to get C. Programming is hard. Life is hard and then you die.

    Guy

    30 May 10 at 11:24 am

  29. But the cost at the call site is predictable in C, while it isn’t in C++. Implicit code generation only happens in C++, and it’s a big problem. (Even Stroustroup agrees on that – read his comments on implicit casts and constructors)

    labmistress

    7 Jun 10 at 8:37 pm

  30. Hello all! I like this forum, i found tons inviting people on this forum.!!!

    Large Community, good all!

    astocactepaiz

    21 Jun 11 at 1:57 pm

  31. Ja tev vajag [b]SEO pakalpojumus, raksti uz seolatvia [at] inbox [dot] lv[/b]

    Visiem ir jāpiekrīt, ka mēs vēlamies redzēt mūsu mājas lapas augšdaļā visus meklētājprogrammu meklēšanas rezultātus! Un vienlaikus mums jāievēro, ka nav iespējams sasniegt šo virsotni panākkum bez pienācīgas Search Engine Optimization (SEO). , lai iegūtu vislabāko rezultātu no SEO, ir nolīgt SEO eksperts. Tagad jautājums nonāk uz jautājumu – Kā nolīgt SEO Expert, lai iegūtu augstākā līmeņa Search Engine Optimization?

    Tirgū ir simtiem Labākie SEO speciālisti Latvijā, no kā izvēlēties, bet mums nav daudz naudas, ko tērēt SEO tikai! Mums ir jāzina, kā būtu meklētājprogrammu optimizācijas speciālistu un ko viņi iesniedz (bet ne solījums). Mēs varam paskatīties uz dažiem būtiskākajiem jautājumiem, kas saistīti ar Search Engine Optimization. Pirms nopirkt Labākais SEO speciālists Latvijā (brīvmākslinieks vai uzņēmums), pārliecinieties, ka tās ir pierādījušas savu SEO portfeli ar panākumiem. SEO jomā, zināšanas un pieredze var veidot tikai vēlamos rezultātus.

    Ir nolīgt SEO eksperts, kas seko pareizai darbībai stratēăiju. No solījumiem nav vērtības. Ir pareiza biznesa procesu analīzes un ētikas process SEO, PPC (par lappusi ārpus lappuses u.c.), lai realizētu potenciālu panākumus. Nevar būt neierobežots ieguldījumu, gaidot rezultātus vai garantēt ātru panākumu. Brīdī, kad nolemj nolīgt SEO Expert, lai viņi zinātu sava projekta termiņu. Konstatē, ka klientiem ir ieguldīt lielu naudu un laiku, tomēr quot%ini%quot ir slikta.

    Skaidri, ja meklētājprogrammas optimizācija gatavojas iekļaut Search Engine Marketing (SEM) vai ne. , iekļaujot izmaiņu un atjaunošanas veicināšanas un vietnes saturu? Tiek konstatēts, ka darbā Labākais SEO speciālists Latvijā, kas galu galā lika jums šo projektu pēc sākuma. Cenšos būt 100 % pārliecināts, ka SEO eksperti ir piekļuve esošajiem un jaunākajiem instrumentiem un tehnoloģijām par SEO. Īre SE eksperts, kas ievēro Google Webmaster pamatnostādu vienlaikus ar jauno Google, Yahoo un citus ziņojumus.

    Neatbilst postu pie$ēmēju rokās. Black-hat ir kā ātri gūt panākumus ar SEO. Citādi var augt savu biznesu (vai pieaudzis) ir aizliegti, vairums meklētājprogrammu. Pat saņemtu zīmogu, dokumentu vai jebkura derīga līguma parakstīšanas, lai aizliegtu šos. Noma [b]Labākais SEO speciālists Latvijā[/b], kas ir spēcīgs saziu. Neizpilda aiz īstenojamības. Konstatē, ka nu no parastā pieejamu pakalpojumu, cilvēki iet uz pakalpojumu sniedzēju un kaūs ar miglaināku seju. Jāsazinās arī sekmīguma proporcija būs mazāka par upuri. Tāpēc es domāju, ka ir skaidrs, ka SEO gan kvalitātes, gan daudzuma mērījumu rezultāti ir tur. Nav saīsne, kā gūt panākumus SEO. Bet panākt, lai virspusē ir iespējams ar pareizu stratēģiju un smagu darbu no ekspertiem. Bez kavēšanās atrodi Labāko SEO speciālistu Latvijā, lai sasniegtu optimālu veiksmes punktu, bet rūpīgi glisādi, saglabājot punktiem rakstīts iepriekš. Atcerēties jaunas metodes, ir un būs. Bet galvenais jautājums paliek tas pats.

    Jauku jums dienu!

    dusFluile

    17 Jul 11 at 1:46 pm

  32. Hello there, simply became aware of your blog via Google, and found that it is truly informative. I’m going to watch out for brussels. I’ll appreciate in the event you continue this in future. A lot of people can be benefited from your writing. Cheers!

  33. Hey, you used to write great, but the last several posts have been kinda boring… I miss your tremendous writings. Past few posts are just a little bit out of track! come on!

    download novels

    12 Aug 11 at 4:53 am

  34. Great film, compelling and mysterious story that keeps you guessing till the very last scene and after

    Ezekiel Standen

    10 Dec 11 at 3:55 pm

  35. And we face the Cardinals tomorrow, and I really dont like our chances of even getting a series split.

    Vivan Canez

    11 Dec 11 at 10:05 pm

  36. Awesome issues here. I’m very happy to look your post. Thank you so much and I’m having a look ahead to contact you. Will you please drop me a mail?

    Mammie Kazda

    12 Dec 11 at 1:41 pm

  37. Thanks for your post on the travel industry. I will also like to add that if you’re a senior taking into account traveling, its absolutely essential that you buy travel cover for seniors. When traveling, elderly people are at biggest risk of experiencing a healthcare emergency. Obtaining the right insurance coverage package to your age group can protect your health and provide peace of mind.

    Locksmith Utah

    19 Dec 11 at 10:32 am

  38. jobba som hudterapeut…

    [...]s This website can be a walk-by way of for the entire information you needed ee[...]…

  39. nepali sexi katha delete plz

    Inoncidedef

    15 May 12 at 1:27 pm

  40. click to read…

    [...]the time to read or visit the content or sites we have linked to below the[...]…

    Tile

    15 May 12 at 5:44 pm

  41. Cool:) I would say say it exploded my brain..!

    Order Cigarettes

    14 Jun 12 at 4:57 pm

  42. where i can find admin?

    prokollim

    23 Aug 12 at 2:59 pm

  43. This is why C++ scares me. I like to know what is going on under the hood, and with C++ it can be very time-consuming to keep track of what is going on. I feel much more comfortable using C to implement high compute-load functionality. (Or C-like C++ to be more precise).

    William Payne

    18 Sep 12 at 11:09 am

  44. You seem to be arguing against abstractions. Yes, abstractions make it harder to estimate performance, but that is the point, they hide details to bring reasoning to a different domain and c++ has more options for abstractions.

    Aaron

    18 Sep 12 at 12:16 pm

  45. [...] The hidden cost of C++ [...]

  46. [...] map very closely to the assembly it generat&#101&#115&#46 [...]

  47. [url=http://www.jpoakleyjapanese.com/ ]オークリー アウトレット [/url]けつるい ふとやか ひとなのか [url=http://www.oakleysunglasjp.com/m-frame-セール-19.html ]オークリー ランニング [/url]かいつける かけっこ ぼやける しょさい しおらしい ひよわ [url=http://www.oakleysunglassjapan.com/オークリー-サングラス-batwolf-セール-22.html ]オークリー ゴルフウェア [/url]ふりこ しずむ さんし [url=http://www.raybansunglassjp.com/レイバン-3459-セール-13.html ]レイバン サングラス 店舗 [/url] くすり にゅういん ストロボ [url=http://www.jpraybanjapan.com/ ]rayban サングラス [/url]どなりたてる じょしゅう たきょう [url=http://www.jpraybansp.com/レイバン-3033-セール-6.html ]レイバン 偽物 [/url] きゅうと ちのみご アタッシェ [url=http://www.raybanjapanese.com/ ]レイバン 眼鏡 [/url]ねこそぎ じゅうとう オフィシャル ルールズ [url=http://www.jpoakleyjp.com/オークリー-frogskins-セール-3.html ]オークリーサングラス [/url] [url=http://www.japanoakleyjp.com/ ]オークリー サングラス 激安 [/url]

    Jeaniedge

    9 Apr 13 at 9:21 pm

  48. I think that is among the so much vital info for me. And i am happy reading your article. However want to remark on some basic issues, The site style is great, the articles is really great : D. Excellent activity, cheers

  49. I was recommended this web site through my cousin.

    I’m now not sure whether or not this publish is written by means of him as no one else know such targeted about my trouble. You’re wonderful! Thanks!

    Wilmer

    9 May 13 at 2:25 am

  50. .

    JackUQ

    5 Jun 13 at 6:14 pm

  51. Hello! Do you know if they make any plugins to protect against hackers?

    I’m kinda paranoid about losing everything I’ve worked hard on.

    Any suggestions?

    コーチ 財布

    12 Jun 13 at 7:12 am

  52. Hello there! This blog post could not be written much better! Reading through this post reminds me of my previous roommate! He always kept talking about this. I will forward this post to him. Pretty sure he’s going to have a very good read. Thanks for sharing!

    Jeferson

    29 Jun 13 at 10:02 am

  53. I like the valuable information you provide in your articles. I will bookmark your blog and check again here regularly. I’m quite certain I will learn many new stuff right here!

    Best of luck for the next!

  54. So here you can save up to 50 to 60% development cost, if you prefer outsourcing provides countries especially Indian companies. Flurry has also worked to improve its own privacy policy to protect consumers so that this type of incident doesn. Right from the start, both parties should be clear about the payment terms.

    app development

    20 Jan 14 at 8:50 pm

  55. WEDGE

    ThekArriweese

    29 Mar 14 at 3:30 pm

  56. Great weblog right here! Additionally your website rather a lot up fast! What host are you using? Can I am getting your affiliate link in your host? I want my web site loaded up as fast as yours lol

    jamie lewis tv

    2 Apr 14 at 12:03 am

  57. It’s hard to find your articles in google. I found it on 17 spot, you should build quality backlinks , it will help you to rank to google top 10. I know how to help you, just type in google – k2 seo tips and tricks

    Modesto

    11 Jul 14 at 9:24 am

  58. Hi there, this weekend is good in support of me, as this point in time i am reading this great educational paragraph here at my home.

  59. I read a lot of interesting posts here. Probably you spend a lot of time writing, i know how to save you a lot of time, there is an online tool that creates readable, SEO friendly articles in minutes, just search in google – laranitas free content source

    Arielle

    23 Aug 14 at 8:36 am

Leave a Reply