庄周梦蝶

生活、程序、未来
   :: 首页 ::  ::  :: 聚合  :: 管理

    越来越觉的JRuby是个很有前途的项目,结合Ruby的性感语法和java极其丰富的类库,况且有团队持续不断地修正bug、改进性能,这样的玩意完全有成为“少男杀手”的潜质。JRuby wiki上列出了性能优化的四条建议:
1、调优编译器,JRuby早就弃暗投明跟随XRuby走上了编译这条牛B的道路,将Ruby Script编译成字节码,因此这个环节是断断不能忽略的。
两种编译方式:
AOT模式:直接生成class文件,脱了Ruby这层皮,咱就是人见人“爱”的java了。
JIT模式:充分利用成熟的jit技术,咱不全脱,朦胧美才是真的美。默认从0.9.9版本开始就是开启的,关闭的话(要我说还不如全脱)
jruby -J-Djruby.jit.enabled=false


2、关闭ObjectSpace
ObjectSpace是Ruby用来操作所有运行时对象的模块,这个功能相当牛x。这个的实现在c ruby里是比较容易的,但是对于JRuby代价就比较昂贵了,其实就大部分情况下你基本用不到这个东东,那么最好就是关闭它,JRuby提供了
jruby -J-Djruby.objectspace.enabled=false
选项来关闭它。

3、开启线程池
我们知道,在c ruby中的线程是绿色的轻量级线程,因此运行时就动不动开个百来十个“线程”跑一跑充下款爷;然而在JRuby中,线程的实现那可是实打实的本地线程(也就是Ruby线程与java线程一比一),你这么动不动上百个线程那不慢才怪了。因此JRuby提供了线程池选项,运行时尽可能地满足你的要求开线程,但是当短命的Ruby线程重复创建的时候,这些线程将被复用,这在大多数情况下能提高性能表现,特别是在每次调用都启动一个线程的情况下。不过具体效果还是要测试的实际数据说话。
jruby -J-Djruby.thread.pooling=true


4、使用Java "server"模式虚拟机,地球淫都知道
jruby -J-server myscript.rb

5、尽量使用最新的jdk,在我的测试中,jdk6跑jruby是效率最高的。

posted @ 2008-01-31 18:58 dennis 阅读(4390) | 评论 (1)编辑 收藏

class BitStruct
  
def self.list(name,element)
    module_eval 
<<-HERE
      rest :body
      
def #{name.to_s}=(elist)
         e=Object.const_get(:#{element})
         if elist.respond_to? :each and elist.respond_to? :[] and elist[0].is_a? e
            elist.each{ 
|value| self.body+=value}
         elsif elist.is_a? e
            self.body
=elist
         
else
            
raise ArgumentError,elist.to_s<<" is not a #{element}",caller
         end
      end
      
def #{name.to_s}
         result=[]
         e
=Object.const_get(:#{element})
         size=e.new.size
         num
=self.body.size/size-1
         
for i in 0..num
            result[i]
=e.new(self.body[i*size,size])
         end
         result
      end
    HERE
  end
end
利用Ruby的动态特性,很容易就达到了,使用的话:

class A <BitStruct
   unsigned :id,
32
end
class B<BitStruct
   list :aList,A
end
alist
=[]
for i in 0..10
  a
=A.new
  a.id
=i
  alist.unshift a
end
b
=B.new
b.aList
=alist
b.aList.each{
|e| puts e.id}

posted @ 2008-01-27 15:53 dennis 阅读(360) | 评论 (0)编辑 收藏

    分析二进制协议或者存取二进制文件是个很常见的需求,Ruby的IO提供了对二进制的读操作,但是写入却只提供字符。并且读的操作也比较笨拙,例如,在c里面的话,我们一般是定义个struct,然后:

fread(record, sizeof(record), 1, stream);

在java里,也是比较容易,特别是nio引入了ByteBuffer之后就更方便了。Ruby的话,我得自己确定读多少个字节,并自己“组装”成原始数据,这显然太麻烦了,幸好,我们有bit-struct :)
    到主页下载,解压之后参照README安装下就OK了。使用的话,也是先定义结构,然后new就行了:
require 'bit-struct'
class Message < BitStruct
    signed :msg_length,
32
    
char   :type,24
    signed :uid,
32
    unsigned :cmd,
16
    rest  :body
end
msg
=Message.new
file.read(msg)
p msg.inspect

bit-struct支持float,char,unsigned,signed,text,pad,nest,oct,hex,其中nest用于声明一个嵌套结构,例如:
class Sub < BitStruct
    unsigned :x,    
8
 end

class A < BitStruct
    nest    :n,  Sub
end

= A.new
p a  
# ==> #<A n=#<Sub x=0>>

如果你看下源码的话,会发现BitStruct继承String类,因此IO可以直接将BitStruct写入文件,内部自动帮你处理转换细节。

posted @ 2008-01-25 18:56 dennis 阅读(1671) | 评论 (0)编辑 收藏

天涯上的牛人真多



posted @ 2008-01-22 14:12 dennis 阅读(397) | 评论 (0)编辑 收藏

    我从来就不是很安分的人,来福州两个月了,在star-net也干了两个月,最后还是经不住诱惑决定去广州了。原因?怎么说呢,在福州的工作没有我想象中的有趣,做的东西都是比较事务性,或者说没有激起我的热情。不过对于在福建的来说,star-net应该还是很好的选择。提辞职对于公司来说挺突然的,不过我做事情从来都是仔细考虑过后才会决定的,如果没有想好就提的话难免让人以为我在要挟什么的。广州那边其实很早就联系了,因为mryufeng老大在那,他帮我推荐了下,很感激老大。说起来跟mryufeng老大认识还通过javaeye,在javaeye上真认识了不少人。去广州的话,很有可能是做服务器开发,主要是java,可能用到cpp、erlang、脚本语言等等,可以说是混合性比较强的工作,不过也有可能去做web开发,这块毕竟是我一直在做的。还是希望能跳出web这个领域,我的兴趣还是在并发和服务器上。
    明天晚上坐长途班车出发,后天一早到广州,准备投靠一哥们,这哥们还是大学时玩网络游戏认识的。在游戏里很投缘,这厮一个人从唐山跑到广州混了两年了,而且混的挺好,不得不让我佩服。先去投靠他几天,然后慢慢找房子,14号就正式去上班了。去了潜心好好干,好好向公司里的老大们学习,毕竟是我最感兴趣的领域啊,机会难得。

posted @ 2008-01-11 15:58 dennis 阅读(615) | 评论 (3)编辑 收藏

    smartclient是一个企业级的ajax框架,包括非常出色的UI库、工具库和客户端服务端数据绑定等功能。smartclient本来是一个商业产品, 2007年11月7号才以LGPL协议开源。除了一些所见即所得的构建工具和企业级的可选组件外,其他都开源了。这个记的javaeye和infoq都有报道。
    在接触smartclient以前,我还没有使用过类似的ajax ui库,比如现在很火的ext。smartclient给我的第一印象是非常漂亮的ui效果,有兴趣可以去它的官方demo看看。smartclient的demo和文档做的非常出色,入手开发也非常容易。
第一步:下载LGPL版本,并解压缩
第二步:运行解压后目录下的\SmartClient_60_LGPL\smartclientSDK\start_embedded_server.bat,SDK自带了一个内嵌的tomcat
第三步:访问 http://localhost:8080

你将见到:


这些demo本身就是用smartclient制作的。开发过程中你需要做就是查看examples和文档中的reference(api文档),基本没有解决不了的问题。

人见人爱的Hello World例子:
isc.Label.create({
    height: 
50,
    styleName: 
"helloWorldText",
    padding: 
4,
    backgroundColor: 
"#ffffd0",
    align: 
"center",
    valign: 
"center",
    wrap: 
false,
    showEdges: 
true,
    showShadow: 
true,
    contents: 
"Hello world!"
})

效果:


    smartclient除了完整的UI组件,还包括丰富的动态效果库以及可选的皮肤等高级主题,不再展开了,毕竟贴图是在是挺麻烦的事情:)还不如有兴趣的自己翻demo。说了这么多优点,那么缺点是啥?你可能猜到了,性能!所有js UI库无法避免的问题,不过我没有其他UI库的使用经验,倒是不能给出个比较数据。我们写的东西的性能也只是堪堪能够接受。
   smartclient跟dwr可以说是天生一对,smartclient UI组件的数据源可以是xml也可以是json,如果采用json做交换格式,可以与dwr无缝结合,真正实现One Page,One Application(我们就是这样做的^_^)。






posted @ 2008-01-08 15:48 dennis 阅读(7482) | 评论 (1)编辑 收藏

    《编程珠玑》第一章第一题就相当的精彩,做个笔记。题目如下:
输入:   一个包含n个正整数的文件,每个正整数小于n,n等于10的7次方(一千万)。并且文件内的正整数没有重复和关联数据。

输出:  输入整数的升序排列
 
约束: 限制在1M左右内存,充足的磁盘空间

    假设整数占32位,1M内存可以存储大概250000个整数,第一个方法就是采用基于磁盘的合并排序算法,第二个办法就是将0-9999999切割成40个区间,分40次扫描(10000000/250000),每次读入250000个在一个区间的整数,并在内存中使用快速排序。书中提出的第三个解决办法是采用bitmap(或者称为bit vector)来表示所有数据集合(注意到条件,数据没有重复),这样就可以一次性将数据读入内存,减少了扫描次数。算法的伪代码如下:
阶段1:初始化一个空集合
     for i=[0,n)
           bit[i]=0;
阶段2:读入数据i,并设置bit[i]=1
    for each i in the input file
           bit[i]=1;
阶段3:输出排序的结果
   for i=[0,n)
          if bit[i]==1
              write i on the output file

这个算法的时间复杂度在O(n),用c语言写的版本可以在10秒内完成任务!c语言的源码在该书主页上有,这里给一个java的测试版,加上我的理解注释:

/**
 * Created by IntelliJ IDEA.
 * User: zhuangxd
 * Date: 2008-1-7
 * Time: 14:30:44
 
*/
public class BitSortTest {
    
private static final int BITSPERWORD = 32;  //整数位数
    private static final int SHIFT = 5;
    
private static final int MASK = 0x1F;  //5位遮蔽 0B11111
    private static final int N = 10000000;
    
//用int数组来模拟位数组,总计(1 + N / BITSPERWORD)*BITSPERWORD位,足以容纳N
    private static int[] a = new int[(1 + N / BITSPERWORD)];

    
public static void main(String[] args) {
        bitsort(
new int[]{11002100009999456778902});
    }

    
public static void bitsort(int[] array) {
        
for (int i = 0; i < N; i++)
            clr(i);   
//位数组所有位清0
        for (int i = 0; i < array.length; i++)
            set(array[i]);  
//阶段2
        for (int i = 0; i < N; i++)
            
if (test(i))
                System.out.println(i);
    }

    
//置a[i>>SHIFT]的第(i & MASK)位为1,也就是位数组的第i位为1
    public static void set(int i) {
        a[i 
>> SHIFT] |= (1 << (i & MASK));
    }

    
//置a[i>>SHIFT]的第(i & MASK)位为0,也就是位数组的第i位为0
    public static void clr(int i) {
        a[i 
>> SHIFT] &= ~(1 << (i & MASK));
    }

    
//测试位数组的第i位是否为1
    public static boolean test(int i) {
        
return (a[i >> SHIFT] & (1 << (i & MASK))) == (1 << (i & MASK));
    }
}



posted @ 2008-01-07 15:30 dennis 阅读(3777) | 评论 (3)编辑 收藏

    提取swf文件元信息、压缩swf、解压swf都可以处理,来自于http://www.brooksandrus.com/blog/category/java/,或者直接这里下载。

一个小例子:
         SWFHeader header = new SWFHeader("G:\\mplayer\\test.swf");
        System.out.println(
"signature:   " + header.getSignature());
        System.out.println(
"version:     " + header.getVersion());
        System.out.println(
"compression: " + header.getCompressionType());
        System.out.println(
"size:        " + header.getSize());
        System.out.println(
"nbits:       " + header.getNbits());
        System.out.println(
"xmax:        " + header.getXmax());
        System.out.println(
"ymax:        " + header.getYmax());
        System.out.println(
"width:       " + header.getWidth());
        System.out.println(
"height:      " + header.getHeight());
        System.out.println(
"frameRate:   " + header.getFrameRate());
        System.out.println(
"frameCount:  " + header.getFrameCount());
 
压缩、解压缩,需要注意生成的文件将覆盖原文件:
//压缩
SWFCompressor compressor=new SWFCompressor("G:\\mplayer\\test.swf");
//解压缩
SWFDecompressor decompressor=new SWFDecompressor("G:\\mplayer\\test.swf");




posted @ 2008-01-04 11:46 dennis 阅读(2983) | 评论 (3)编辑 收藏

update:2008-05-05,POI已经可以处理这个需求:
package net.rubyeye.test;

import java.io.FileOutputStream;

import org.apache.poi.hslf.HSLFSlideShow;
import org.apache.poi.hslf.model.Picture;
import org.apache.poi.hslf.usermodel.PictureData;
import org.apache.poi.hslf.usermodel.SlideShow;

public class PPTToImageConverter {
    
public static void main(String[] args) throws Exception {
        SlideShow ppt 
= new SlideShow(new HSLFSlideShow("D:/test.ppt"));

        
// extract all pictures contained in the presentation
        PictureData[] pdata = ppt.getPictureData();
        
for (int i = 0; i < pdata.length; i++) {
            PictureData pict 
= pdata[i];

            
// picture data
            byte[] data = pict.getData();

            
int type = pict.getType();
            String ext;
            
switch (type) {
            
case Picture.JPEG:
                ext 
= ".jpg";
                
break;
            
case Picture.PNG:
                ext 
= ".png";
                
break;
            
case Picture.WMF:
                ext 
= ".wmf";
                
break;
            
case Picture.EMF:
                ext 
= ".emf";
                
break;
            
case Picture.PICT:
                ext 
= ".pict";
                
break;
            
default:
                
continue;
            }
            FileOutputStream out 
= new FileOutputStream("D:/test/pict_" + i + ext);
            out.write(data);
            out.close();

        }
    }
}

   原文:
   小结下最近做的东西吧。因为是做一个素材管理的东西,因此需要处理各种各样的素材,音频、视频、图片、pdf、ppt等等。遇到一个需求就是将PPT转成图片组,google一下,在java里是可以jcom之类的开源库实现,本质上都是通过jni调用office的COM接口来实现。我们就需要这么一个小功能,拖这么大个开源库进来实在没有必要。最后决定自己写个动态链接库,通过jni来调用。
    先写工具类,
public class PPTUtils {
    
public PPTUtils() {
    }

    
public static native void convertPPT2IMG(String pptFileName, String tmpDir);

 
   public static void loadLibrary() {//加载动态库
        String dllFileName = "pptDll";
        
try {
            String OsName 
= System.getProperty("os.name");
            
if (OsName.contains("Windows")) {
                dllFileName 
+= ".dll";
            } 
else {
                dllFileName 
+= ".so";
            }
            
//加载动态链接库
            System.load(dllFileName);
         
        }
        
catch (Exception e) {
         
//   LOG.error("can not load " + dllFileName + ", " + e.getMessage());
            e.printStackTrace();
        }
     }
}

    编译一下,执行javah PPTUtils生成头文件PPTUtils.h。接下来用vc写个动态链接库,记的将MSPPT.OLB(在office安装目录下)加入工程,新建一个ppt2img.cpp:
#include "stdafx.h"
#include 
"PPTUtils.h"
#include 
"msppt.h"

JNIEXPORT 
void JNICALL Java_com_starnet_dmb_util_PPTUtils_convertPPT2IMG(JNIEnv *env,
      jclass clazz, jstring pptFileName, jstring tmpDir){
   
//初始化com
    if (CoInitialize( NULL ) == E_INVALIDARG)
    {
       AfxMessageBox(_T(
"初始化Com失败!"));
       
return;
    }  
    _Application   app;
    Presentations   prsts;
    _Presentation   prst;
    
//jstring转成char *
   const char *ppt;
   ppt 
= env->GetStringUTFChars(pptFileName,0);
   
const char *tmp;
   tmp
=env->GetStringUTFChars(tmpDir,0);

   
if(!app.CreateDispatch(_T("PowerPoint.Application"))){
      AfxMessageBox(_T(
"初始化PowerPoint失败!"));
       
return;
   }
   prsts   
=   app.GetPresentations();
   prst   
=   prsts.Open(_T(ppt),false,false,false);
   prst.SaveAs(_T(tmp),
17,false);
   app.ReleaseDispatch();
   app.Quit();
   env
->ReleaseStringUTFChars(pptFileName,ppt);
   env
->ReleaseStringUTFChars(tmpDir,tmp);
   CoUninitialize();
}

posted @ 2008-01-04 11:26 dennis 阅读(4360) | 评论 (0)编辑 收藏

    挺久没动笔写blog了,换了新工作比较忙是一个原因。最近的工作是做一个素材管理的系统,其中有个要求做视频预览,将用户上传的视频转换并在网页上预览。在网页上看视频,现在大多数视频网站都是采用flv流媒体文件,用flash做的播放器播放,我们也采用了这种方式。流程大概主要:用户上传文件->后台转换文件成flv格式->flv播放器调用flv文件。
    转换视频、音频文件到flv格式可以使用mencoder或者ffmpeg,我们采用了mencoder,在linux上的安装参考这里,安装结束后记的设置环境变量:export LD_LIBRARY_PATH=/usr/local/lib:LD_LIBRARY_PATH
    java调用的话就是通过Process:
 Process process = runtime.exec(cmd);

mencoder转换视频音频成flv命令:
mencoder 源文件 -o 目标文件.flv -of lavf    -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames -oac mp3lame -lameopts abr:br=56 -ovc lavc -lavcopts vcodec=flv:vbitrate=400:mbd=2:mv0:trell:v4mv:cbp:last_pred=3:dia=4:cmp=6:vb_strategy=1 -vf scale=200:-3 -ofps 12 -srate 22050

取视频元信息命令(视频比特率、长宽等信息):
mplayer -identify 文件名 -ao null -vo null -frames 0

切割视频命令:
mencoder -ss 开始时间 -oac copy -ovc copy -endpos 终止时间 文件名 -o 目标文件名

    操作flv文件(给视频打上信息、切割之类)可以采用flvtool2
   
    需要注意的是通过java调用的话,一定要处理标准输出和标准错误输出,不然进程会挂在那结束不了,可以开个线程取处理。在网页播放的话,可以考虑用这个播放器,具体参数看它的说明。最后一个问题,IE6的flash控件需要激活,这个问题的解决可以采用swfobject.js
    有兴趣的老大们可以考虑自己搭个“土豆网”,说不定哪天拿了风投.....浮云

posted @ 2007-12-19 16:46 dennis 阅读(7294) | 评论 (5)编辑 收藏

仅列出标题
共56页: First 上一页 30 31 32 33 34 35 36 37 38 下一页 Last