2009-08-06 44 views
0

由於其良好的結構和RDBO比CDBI和DBIC更快的術語,我計劃從Class :: DBI遷移到Rose :: DB :: Object。我的Rose :: DB :: Object編譯時間太慢了嗎?

但是我的機器(Linux的2.6.9-89,Perl的5.8.9)RDBO編譯時間上比CDBI慢得多:

 
$ time perl -MClass::DBI -e0 
real 0m0.233s 
user 0m0.208s 
sys  0m0.024s 

$ time perl -MRose::DB::Object -e0 
real 0m1.178s 
user 0m1.097s 
sys  0m0.078s 

這是一個很多不同...

任何人都有類似的行爲?

乾杯。


@manni和@約翰:感謝有關RDBO引用的模塊的解釋,那肯定回答爲什麼編譯時間比CDBI慢。

該應用程序未運行在持久性環境中。事實上,它是由幾個同時執行cron作業,運行時間爲2分鐘,5分鐘和x分鐘間隔 - 是的,編譯時間是至關重要的...

Jonathan Rockway的應用程序::持久看似有趣,但其(當前)限制只允許一次運行的應用程序不適合我的目的。此外,它有問題,當我們殺了客戶端,服務器進程仍在運行...

+0

加載時間只是一個問題,如果你沒有運行在一個持久化的環境中(比如mod_perl或者FastCGI),你真的應該(因爲FastCGI託管這些天很便宜,所以沒有任何理由)。而且,對於大多數應用程序而言,運行時間佔總時間的百分比遠遠超過啓動時間。 – mpeters 2009-08-06 14:16:47

+0

@mpeters:誰說他要構建一些網絡應用程序? – innaM 2009-08-06 17:11:02

回答

1

這看起來幾乎是戲劇性的在這裏:

time perl -MClass::DBI -e0 
real  0m0.084s 
user  0m0.080s 
sys  0m0.004s 

time perl -MRose::DB::Object -e0 
real  0m0.391s 
user  0m0.356s 
sys  0m0.036s 

我的差異恐怕一部分可以簡單地解釋通過依賴的每個模塊中的數量:

perl -MClass::DBI -le 'print scalar keys %INC' 
46 

perl -MRose::DB::Object -le 'print scalar keys %INC' 
95 

當然,你應該問自己多少編譯時間真的很重要爲您的特定問題。哪些源代碼更容易爲您維護。

5

Rose::DB::Object簡單包含(或從其它模塊的引用)比Class::DBI得多的代碼。在光明的一面,它也有many more featuresmuch faster at runtime比Class :: DBI。如果編譯時間是你的問題,那麼你最好的辦法就是儘可能少加載代碼(或者加快磁盤速度)。

另一種選擇是設置auto_load_related_classes爲false在您的元數據對象。要儘早做到這一點,全球可能需要您製作一個Metadata子類,然後將其設置爲您的常見Rose::DB::Object基類中的meta_class

打開auto_load_related_classes關閉意味着你不得不手動加載你真的想在你的腳本中使用相關的類。這有點痛苦,但它可以讓你控制有多少類被加載。 (如果您有大量相互關聯的類,加載一個人可以最終拉動所有其他的人英寸)

你可以,也許,有一個環境變量來控制行爲。例如元數據類:

package My::DB::Object::Metadata; 

use base 'Rose::DB::Object::Metadata'; 

# New class method to handle default 
sub default_auto_load_related_classes 
{ 
    return $ENV{'RDBO_AUTO_LOAD_RELATED_CLASSES'} ? 1 : 0 
} 

# Override existing object method, honoring new class-defined default 
sub auto_load_related_classes 
{ 
    my($self) = shift; 

    return $self->SUPER::auto_load_related_classes(@_) if(@_); 

    if(defined(my $value = $self->SUPER::auto_load_related_classes)) 
    { 
    return $value; 
    } 

    # Initialize to default 
    return $self->SUPER::auto_load_related_classes(ref($self)->default_auto_load_related_classes); 
} 

,這裏是它是如何與您的共同對象的基類:

package My::DB::Object; 

use base 'Rose::DB::Object'; 

use My::DB::Object::Metadata; 

sub meta_class { 'My::DB::Object::Metadata' } 

然後,當你在一個持續的環境中運行設置RDBO_AUTO_LOAD_RELATED_CLASSES爲真,並把它假(並且不要忘記爲命令行腳本顯式加載相關的類)。

同樣,如果由於默認的auto_load_related_classes元數據屬性的真實值,您目前正在加載比您在特定腳本中嚴格需要的類更多的類,這隻會有所幫助。

+0

對不起,很長的響應延遲... 我必須先完成實施,並且現在已經完成並且所有測試通過,我將返回到性能優化。 但是,按照上面的建議不會提高編譯時間? %INC中加載的模塊數量保持不變。 該文檔說,當這個類初始化時,會自動加載「auto_load_related_classes」,我認爲這發生在我通過My​​ :: DB :: Object調用「sub init_db {My :: DB-> new()}」時發生。 – est 2009-08-31 07:27:46

+0

不,這意味着如果加載類A並且它與類B有關係,那麼如果auto_load_related_classes()爲true,則會自動加載類B.如果您已經手動加載了A和B類,那麼顯然這個設置不起作用。 – 2009-08-31 13:21:00

+0

啊,現在開始有意義了。我想要更快的磁盤將成爲我的案例... – est 2009-09-01 01:51:18

3

如果編譯時間是個問題,有一些方法可以降低影響。一個是PPerl,它將普通的Perl腳本編譯成一次編譯的守護進程。你需要做(安裝後,當然)唯一的變化是把家當行:

#!/usr/bin/pperl 

另一種方法是代碼編寫,其中的大部分工作是由做了客戶機/服務器模式應用程序加載昂貴模塊的服務器以及僅通過套接字或管道與服務器交互的瘦腳本。

你也應該看看App::Persistentarticle,這兩個都是由Jonathan Rockway(又名jrockway)寫的。