The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Well, actually I meant "mongrel" or "webrick". The server caches the Ruby classes in production mode. I am not sure whether it can cache the "raw" classes and mixins seperately or whether a class mixed with a module will stay forever "mixed". The first case could conceivably also lead to some semantic problems while the latter obviously will take less advantage of the cache.

On the surface reference counting looks decievingly simple. But once you dive into it you discover that fragmentation is soon becoming a big problem. You are not done simply by "deallocating" the memory. Hence, free-space consolidation is also needed (in PHPs case I believe this is simply just the trusty old malloc and free from the C runtime). But this is where the generational GCs excels. Because they free a lot of fragments in address order (by walking "next" pointers) they have a comparatively simple job when merging the free fragments into larger regions. Reference counting has to use free lists (hoping that someone will allocate something of that size again) or find other ways to categorize and merge neighboring fragments.

Anyway, subjective perhaps, but performance is far from my main concern, when it comes to PHP. There are plenty of large sites, running on PHP.

I hear you. But the argument was made that as the frameworks grow in complexity (in the name of developer productibity) this "throw everything away and create it next time" could become a serious bottleneck. I think you are already seeing some of that now.

I pointed out that Ruby (there, I remembered it) had some of the same problems, but solved it by caching the finished class definitions when in production mode, rather than just caching the opcodes which will build the classes once executed.

Add to that the fact that processors are not going to get much faster; they are going to get multiple cores. Now, anything which requires a lenghty, single-threaded (within a single process) prologue for each request is not going to be able to take advantage of multiple cores to address this scalability issue. Each core will still need to execute the entire script for each request. Each core is not going to get much faster than what we see today; possibly even slower as a trade-off for having many cores.

I guess that what I'm adressing here is that touting the "throw everything away" as a performance advantage is wrong. It is almost the opposite; it is a scalability (scaling with complexity/number of classes) problem in the works. It is a great reliability precaution, because any errors made my the interpreter (like failing to reclaim circular references) does not matter a few seconds later because the entire memory is thrown away. I'm not sure you will have that luxury in the future.

Well, actually I meant "mongrel" or "webrick". The server caches the Ruby classes in production mode. I am not sure whether it can cache the "raw" classes and mixins seperately or whether a class mixed with a module will stay forever "mixed". The first case could conceivably also lead to some semantic problems while the latter obviously will take less advantage of the cache.

I'm not sure how accurate it is to use the word "cache" in this context; the objects are simply created and left in memory. I'm also quite certain that classes are stored in their "mixed" state, although I don't know this for sure...

A couple of years ago, PHP sat at the top of the powerful-but-easy-to-use scripting languages heap -- at least as far as popularity was concerned. It was installed on most UNIX&#174; and Linux&#174;-based Web servers. And if you were a programmer, it was easy to get a hosting account that would let you use it. Ruby had been around for quite some time, but not many people were using it. If you wanted to build a Web site using dynamically generated content, but you weren't sure that you needed to go so far as to use an application server like J2EE, you would very likely use PHP. It was fast, easy to learn, convenient, and you didn't have to learn Perl.

And then -- suddenly, it seemed -- the landscape changed. Ruby on Rails hit the programming world like a truck. Object-oriented and based on the Model-View-Controller (MVC) paradigm, Ruby on Rails presented a way to do what we all want to do: create a Web site with virtually no effort. Of course, there were still two problems. For one thing, you had to learn a new programming language. That's not a trivial task, no matter what the language. And for another thing, if you found a host that would let you run Ruby on Rails, you were very lucky. Most wouldn't. If you've had the same account for a decade (as I have), you might be a little slow to switch just because they don't have a new programming language. Then, of course, there was the issue of all of the existing PHP code you've written over the years. Did you really want a ditch it all and start over? Of course not!

RoR hit the programming world with its OOP based on the MVC paradigm, no one can argue that. The problem with RoR is that, unlike PHP, it wasn't built for the web. And now, that web services are becoming more and more popular, only a few web-based programming languages are up for the challenge, and PHP is one of them.

A better architecture than MVC? MVC is not an architecture, it's a pattern that's part of a system architecture, along with many other patterns, like the front controller for example. And like any other pattern, it's there to solve a particular problem, and that's it. I'm sure that future architectures are not going to be based on this pattern, maybe on DSP, or an architectural pattern product of SOA. Who knows, it's up to you to come up with something new and different. That's why your boss hired you god damit

The RoR team set a path with MVC, follow only if you are lost, or if you are not doing anything interesting, like web services for example.

MVC is both an architecture and a pattern. It's an architecture in the way that it defines how your app will be structured, and a pattern in the way that it solves the separate-business-and-presentation-logic problem. Most of the time, anyways.

Of course, you can use MVC only for smaller bits in your app, but that doesn't make it less of an architecture...

No, it's not an architecture and a pattern. It's an architectural pattern, they are different things, patterns are part of the architecture of a system. Like the front controller pattern for example, it's not the architecture of a system.

Well, actually I meant "mongrel" or "webrick". The server caches the Ruby classes in production mode.

That's nifty. I didn't know that.

Originally Posted by honeymonster

I hear you. But the argument was made that as the frameworks grow in complexity (in the name of developer productibity) this "throw everything away and create it next time" could become a serious bottleneck.

Fair enough, but I still think that lazy loading can prevent us from hitting that wall, in the nearest future. Of course, that presupposes that frameworks are structured in a fundamentally different way, than Java and such.

Originally Posted by honeymonster

ingle-threaded (within a single process) prologue for each request is not going to be able to take advantage of multiple cores to address this scalability issue. Each core will still need to execute the entire script for each request. Each core is not going to get much faster than what we see today; possibly even slower as a trade-off for having many cores.

As long as a single request fits in a single process, then that process could be distributed out over multiple cores, I suppose. Admittedly, I don't know if Apache/mod_php supports that currently, but they could.

Originally Posted by honeymonster

On the surface reference counting looks decievingly simple. But once you dive into it you discover that fragmentation is soon becoming a big problem.

Originally Posted by honeymonster

I guess that what I'm adressing here is that touting the "throw everything away" as a performance advantage is wrong. It is almost the opposite; it is a scalability (scaling with complexity/number of classes) problem in the works. It is a great reliability precaution, because any errors made my the interpreter (like failing to reclaim circular references) does not matter a few seconds later because the entire memory is thrown away. I'm not sure you will have that luxury in the future.

The problem with RoR is that, unlike PHP, it wasn't built for the web. And now, that web services are becoming more and more popular, only a few web-based programming languages are up for the challenge, and PHP is one of them.

PHP was built for the web... the way it existed over 10 years ago. The web has changed a lot since then, web apps are getting more like desktop apps, and PHP's cgi-bin roots are becoming a liability; this is exactly what we've been discussing regarding PHP's reference counted garbage collection.

PHP will remain the number 1 choice for small scripts, which is what the majority of the websites out there need anyway, but for more complex applications other languages have many advantages over PHP.

Multi-threading is something that can be useful in every level of the application; the scripts can benefit form it as much as everything else.

I disagree. Frameworks (and also well-structured user OO code) build up more complex classes from simpler classes, either by inheritance, aggregation or simply by using them temporarily. Until the simpler classes are built, the classes which rely upon them cannot be built. This makes the typical PHP prologue an inherently imperative process which does not lend itself easily (if at all) to concurrent execution. By closely analyzing the source code you may be able to perform some class definitions in parallel (if PHP ever get to support threads in the web environment), but nothing in the language design will support you in this.

I disagree. Frameworks (and also well-structured user OO code) build up more complex classes from simpler classes, either by inheritance, aggregation or simply by using them temporarily. Until the simpler classes are built, the classes which rely upon them cannot be built.

Actually, one might use a top-down approach to software development; this is commonly not the case but on does not have to suffer from the Architecture by implication Anti-Pattern. It is more common, however, to use a bottom-up approach.

This makes the typical PHP prologue an inherently imperative process which does not lend itself easily (if at all) to concurrent execution.

Applications written in PHP benefit form multi-threading as much as every other language that has support for them. Although only a hand full of developers in the PHP community will have a concurrent mind-set their are some obvious benefits to having multi-threading support for it. Although we currently have Fiber support, 'threads' that are managed on an application level instead of the operating system level, using the tick()-keyword, it is highly impractical and cumbersome to use.

By closely analyzing the source code you may be able to perform some class definitions in parallel (if PHP ever get to support threads in the web environment), but nothing in the language design will support you in this.

Most multi-threading implementations are done on a framework level and as such most languages only have to provide minimal accommodations for concurrent programming. However, I do suspect that PHP might currently not be up for the task.

On a side-note: class definitions don't happen in parallel (unless PHP might decide to split up it's parsing sage into multiple threads or do some other voodoo magic); it's the code execution (e.g. the runtime) that happens in parallel.