java restful教學 - 如何在url請求中發送數組



service教學 spring (2)

我的要求如下:

我想給演員姓名,開始日期,結束日期,並獲得他在那個時期演出的所有電影。

出於這個原因,我的服務請求是這樣的。

  http://localhost:8080/MovieDB/GetJson?name=Actor&startDate=20120101&endDate=20120505

現在,我想改進它。 我想給出開始日期,結束日期和多個演員姓名,並希望在那段時間內看到所有演員電影。

我不確定我的網址應該如何支持這樣的事情。

我正在使用spring編寫基於Java的Web服務。

下面的代碼是支持一個actor

   @RequestMapping(value = "/GetJson", method = RequestMethod.GET) 
    public void getJson(@RequestParam("name") String ticker, @RequestParam("startDate") String startDate, @RequestParam("endDate") String endDate) {
   //code to get results from db for those params.
 }

我想的一個解決方案是使用%符號來分隔演員姓名。 例如:

 http://localhost:8080/MovieDB/GetJson?name=Actor1%Actor2%Actor3&startDate=20120101&endDate=20120505

現在,在控制器中,我將使用%解析名稱字符串並獲取所有actor名稱。

這是一個很好的方法嗎?還是有標準方法?

謝謝


Answers

用逗號分隔:

http://localhost:8080/MovieDB/GetJson?name=Actor1,Actor2,Actor3&startDate=20120101&endDate=20120505

要么:

http://localhost:8080/MovieDB/GetJson?name=Actor1&name=Actor2&name=Actor3&startDate=20120101&endDate=20120505

要么:

http://localhost:8080/MovieDB/GetJson?name[0]=Actor1&name[1]=Actor2&name[2]=Actor3&startDate=20120101&endDate=20120505

無論哪種方式,您的方法簽名都必須是:

@RequestMapping(value = "/GetJson", method = RequestMethod.GET) 
public void getJson(@RequestParam("name") String[] ticker, @RequestParam("startDate") String startDate, @RequestParam("endDate") String endDate) {
   //code to get results from db for those params.
 }

當數據被排序時,性能提高的原因是分支預測懲罰被消除,正如的答案中精美地解釋的那樣。

現在,如果我們看一下代碼

if (data[c] >= 128)
    sum += data[c];

我們可以發現這個特殊的if... else...分支的含義是在條件滿足時添加一些東西。 這種類型的分支可以很容易地轉換為條件移動語句,它將被編譯成x86系統中的條件移動指令: cmovl 。 分支以及因此潛在的分支預測懲罰被移除。

CC++ ,這個語句可以直接編譯(沒有任何優化)到x86的條件移動指令,是三元運算符... ? ... : ... ... ? ... : ... 所以我們將上面的語句重寫為等價的語句:

sum += data[c] >=128 ? data[c] : 0;

在保持可讀性的同時,我們可以檢查加速因子。

在Intel Core i7 -2600K @ 3.4 GHz和Visual Studio 2010發布模式下,基準是(從Mysticial複製的格式):

86

//  Branch - Random
seconds = 8.885

//  Branch - Sorted
seconds = 1.528

//  Branchless - Random
seconds = 3.716

//  Branchless - Sorted
seconds = 3.71

64位

//  Branch - Random
seconds = 11.302

//  Branch - Sorted
 seconds = 1.830

//  Branchless - Random
seconds = 2.736

//  Branchless - Sorted
seconds = 2.737

結果在多個測試中是穩健的。 當分支結果不可預測時,我們獲得了很大的加速,但是當它是可預測的時候我們會受到一點點的影響。 實際上,在使用條件移動時,無論數據模式如何,性能都是相同的。

現在讓我們通過調查它們生成的x86程序集來更仔細地查看。 為簡單起見,我們使用max1max2兩個函數。

max1使用條件分支if... else ...

int max1(int a, int b) {
    if (a > b)
        return a;
    else
        return b;
}

max2使用三元運算符... ? ... : ... ... ? ... : ...

int max2(int a, int b) {
    return a > b ? a : b;
}

在x86-64機器上, GCC -S生成下面的組件。

:max1
    movl    %edi, -4(%rbp)
    movl    %esi, -8(%rbp)
    movl    -4(%rbp), %eax
    cmpl    -8(%rbp), %eax
    jle     .L2
    movl    -4(%rbp), %eax
    movl    %eax, -12(%rbp)
    jmp     .L4
.L2:
    movl    -8(%rbp), %eax
    movl    %eax, -12(%rbp)
.L4:
    movl    -12(%rbp), %eax
    leave
    ret

:max2
    movl    %edi, -4(%rbp)
    movl    %esi, -8(%rbp)
    movl    -4(%rbp), %eax
    cmpl    %eax, -8(%rbp)
    cmovge  -8(%rbp), %eax
    leave
    ret

由於使用了指令cmovge max2使用的代碼要少cmovge 。 但真正的好處是max2不涉及分支跳轉, jmp ,如果預測結果不正確,則會產生顯著的性能損失。

那麼為什麼有條件的移動表現更好呢?

在典型的x86處理器中,指令的執行分為幾個階段。 粗略地說,我們有不同的硬件來處理不同的階段。 因此,我們不必等待一條指令完成開始新指令。 這稱為pipelining

在分支情況下,以下指令由前一個指令確定,因此我們不能進行流水線操作。 我們必須等待或預測。

在條件移動的情況下,執行條件移動指令被分成幾個階段,但是像FetchDecode這樣的早期階段不依賴於前一個指令的結果; 只有後期才需要結果。 因此,我們等待一個指令執行時間的一小部分。 這就是為什麼當預測很容易時,條件移動版本比分支慢。

計算機系統:程序員視角 ”一書第二版詳細解釋了這一點。 您可以檢查第3.6.6節有關條件移動指令 ,整個第4章用於處理器體系結構 ,第5.11.2節用於特殊處理分支預測和錯誤預測懲罰

有時,一些現代編譯器可以優化我們的代碼以便以更好的性能進行彙編,有時一些編譯器不能(有問題的代碼使用Visual Studio的本機編譯器)。 在不可預測的情況下了解分支和條件移動之間的性能差異可以幫助我們在場景變得如此復雜以至於編譯器無法自動優化它們時編寫具有更好性能的代碼。





java web-services spring url spring-mvc