From: David Masover Date: 2009-11-20T17:28:29+09:00 Subject: Re: UDP Proxy On Friday 20 November 2009 12:24:16 am Randy General wrote: > My goal is to make a UDP Proxy. Basically it will be initialized with an > IP (ip_x), and if any packets are sent to the proxy, it will re-send > them to ip_x, take any response ip_x sends to the packet, and return it > to the client. Question #1: Would port forwarding work for this? It looks like a simple DNAT filter on Linux, for example. > I've tried someone else's implementation of this in C, > and it worked quite well. However, while my code works, it's > tremendously slow. I attempted to play a game through the proxy, and it > was exceptionally slow. Question #2: If you've got an implementation in C, why do you need one in Ruby? If you're wanting to do fancier things in Ruby, would it work to use the C version as a library? > Is the poor performance of the script a result of poor coding on my > part? Or is an interpreted language like Ruby incapable of efficiently > doing this sort of task? It wouldn't be that Ruby is interpreted. It might be that Ruby is slow. Keep in mind that Lisp can be interpreted, and can also run faster than C. For that matter, C can be interpreted, too. There's a few things you're doing that just feel wrong from a performance standpoint: data = [] parts.each do |part| data += part[0..-2] template << part[-1] end So wait -- you're doing += on an array, but << on a string? I'm not sure if << is more efficient on a string, but it certainly is on an array. Change that to: data << part[0..-2] If you didn't know, += in Ruby is expanded to: data = data + part[0..-2], which likely means one full array copy per part. You're also doing a lot of binary packing and unpacking, and building packets out of arrays, which makes me wonder if there's a higher-level library you could use for manipulating UDP packets. Make sure you're at least using Ruby 1.9 (that's twice the speed of 1.8), and try JRuby. And finally: Run it through some profiling, to see where your bottlenecks actually are. I think that's the best way to figure out if it can be done. But I'm not really sure, maybe someone more knowledgeable can tell you, for instance, how many packets per second you'd expect, and if that runs into some hard limit on the number of cycles per Ruby function call or something like that.