From patchwork Wed Oct 5 16:47:21 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rodriguez Betancourt, Esteban" X-Patchwork-Id: 678530 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3sq1sr6cMwz9rxw for ; Thu, 6 Oct 2016 03:47:28 +1100 (AEDT) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 1F68A105B0; Wed, 5 Oct 2016 09:47:28 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e4.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id 9D92C102DE for ; Wed, 5 Oct 2016 09:47:26 -0700 (PDT) Received: from bar5.cudamail.com (unknown [192.168.21.12]) by mx1e4.cudamail.com (Postfix) with ESMTPS id 315211E06D0 for ; Wed, 5 Oct 2016 10:47:26 -0600 (MDT) X-ASG-Debug-ID: 1475686045-09eadd4e17153620001-byXFYA Received: from mx3-pf2.cudamail.com ([192.168.14.1]) by bar5.cudamail.com with ESMTP id GUHATl2i295Itrmm (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 05 Oct 2016 10:47:25 -0600 (MDT) X-Barracuda-Envelope-From: estebarb@hpe.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.14.1 Received: from unknown (HELO NAM03-BY2-obe.outbound.protection.outlook.com) (104.47.42.103) by mx3-pf2.cudamail.com with ESMTPS (AES256-SHA encrypted); 5 Oct 2016 16:47:23 -0000 Received-SPF: none (mx3-pf2.cudamail.com: domain at hpe.com does not designate permitted sender hosts) X-Barracuda-Apparent-Source-IP: 104.47.42.103 X-Barracuda-RBL-IP: 104.47.42.103 Received: from AT5PR84MB0210.NAMPRD84.PROD.OUTLOOK.COM (10.162.138.148) by AT5PR84MB0209.NAMPRD84.PROD.OUTLOOK.COM (10.162.138.147) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.649.16; Wed, 5 Oct 2016 16:47:22 +0000 Received: from AT5PR84MB0210.NAMPRD84.PROD.OUTLOOK.COM ([10.162.138.148]) by AT5PR84MB0210.NAMPRD84.PROD.OUTLOOK.COM ([10.162.138.148]) with mapi id 15.01.0649.021; Wed, 5 Oct 2016 16:47:22 +0000 X-CudaMail-Envelope-Sender: estebarb@hpe.com From: "Rodriguez Betancourt, Esteban" To: "dev@openvswitch.org" X-CudaMail-MID: CM-V2-1004029881 X-CudaMail-DTE: 100516 X-CudaMail-Originating-IP: 104.47.42.103 Thread-Topic: [PATCH v2 1/1] json: Serialize strings using a lookup table X-ASG-Orig-Subj: [##CM-V2-1004029881##][PATCH v2 1/1] json: Serialize strings using a lookup table Thread-Index: AdIfJ3sdIXEILNeUT2q1izmMK+pLLA== Date: Wed, 5 Oct 2016 16:47:21 +0000 Message-ID: Accept-Language: es-ES, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=estebarb@hpe.com; x-originating-ip: [15.203.227.3] x-ms-office365-filtering-correlation-id: 8d9d9fb5-f5ba-43e8-1066-08d3ed3f4731 x-microsoft-exchange-diagnostics: 1; AT5PR84MB0209; 7:gjpMruoO2nytzjr6hTLiyY5ZOW84glkOkEePCsIwOp12QSAxWajVF/ShGL3tUOhr+us5UGFHU3/R3Q6x/D9i89bG/j/A4Mt3J85otapfpOpDqDnyH6tIfD5C9aofdXtDu6mn84YmQdGVJ62yIhA/WtGKdSG/Ugc6QhVfZASe4W/oK6L5ZHU2Z+bzyS+U+lq4YpRDthzpJUJu3GMihg/nmwi1OP4mrL+sjYrk7pH4D2i99Cxvz80KeFrI3kJwsN/to4NmZl8IYY4OrR4HbnDGAQx7WEsgPzP8StWmQyhTI+j75J4mhfXI8YPZgYj/T6aDlImoRTCj8JOe8rqf/Xrq8A== x-microsoft-antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:AT5PR84MB0209; x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(227479698468861); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6055026); SRVR:AT5PR84MB0209; BCL:0; PCL:0; RULEID:; SRVR:AT5PR84MB0209; x-forefront-prvs: 008663486A x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(6009001)(7916002)(189002)(199003)(87936001)(2501003)(7736002)(9686002)(66066001)(33656002)(105586002)(305945005)(110136003)(5002640100001)(7696004)(2351001)(19580405001)(3280700002)(229853001)(19580395003)(189998001)(11100500001)(99286002)(3660700001)(106356001)(10400500002)(86362001)(74316002)(7846002)(97736004)(1730700003)(5640700001)(68736007)(81166006)(8676002)(6916009)(81156014)(50986999)(450100001)(101416001)(77096005)(2900100001)(122556002)(3846002)(102836003)(2906002)(8936002)(6116002)(5660300001)(54356999)(92566002)(586003)(107886002); DIR:OUT; SFP:1102; SCL:1; SRVR:AT5PR84MB0209; H:AT5PR84MB0210.NAMPRD84.PROD.OUTLOOK.COM; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; received-spf: None (protection.outlook.com: hpe.com does not designate permitted sender hosts) spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: hpe.com X-MS-Exchange-CrossTenant-originalarrivaltime: 05 Oct 2016 16:47:21.9209 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 105b2061-b669-4b31-92ac-24d304d195dc X-MS-Exchange-Transport-CrossTenantHeadersStamped: AT5PR84MB0209 X-GBUdb-Analysis: 0, 104.47.42.103, Ugly c=0.372106 p=-0.0810811 Source Normal X-MessageSniffer-Rules: 0-0-0-14087-c X-Barracuda-Connect: UNKNOWN[192.168.14.1] X-Barracuda-Start-Time: 1475686045 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using global scores of TAG_LEVEL=3.5 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=4.0 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.33495 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS Subject: [ovs-dev] [PATCH v2 1/1] json: Serialize strings using a lookup table X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@openvswitch.org Sender: "dev" The existing implementation uses a switch with many conditions, that when compiled is translated to a not optimal series of conditional jumps. With a lookup table the generated code has less conditional jumps, that should translate in improving the CPU ability to predict the jumps. Performance Comparison: All the timings are in nanoseconds, "OVS Master" corresponds to 13a1d36. N is the number of repetitions Serialize vswitch.ovsschema N OVS Master Lookup Table Difference Diff per op 1 233182 200369 32813 32813 10 2724931 1919168 805763 80576.3 100 22802794 24406648 -1603854 -16038.54 1000 253645888 206259760 47386128 47386.128 10000 2352245703 1906839780 445405923 44540.5923 100000 23967770920 19012178655 4955592265 49555.92265 Serialize echo example N OVS Master Lookup Table Difference Diff per op 1 3857 12565 -8708 -8708 10 17403 7312 10091 1009.1 100 57859 56613 1246 12.46 1000 592310 528110 64200 64.2 10000 6096334 5576109 520225 52.0225 100000 60970439 58477626 2492813 24.92813 Serialize mutate example N OVS Master Lookup Table Difference Diff per op 1 7115 19051 -11936 -11936 10 34110 39561 -5451 -545.1 100 296613 298645 -2032 -20.32 1000 3510499 2930588 579911 579.911 10000 33898710 30278631 3620079 362.0079 100000 305069356 280622992 24446364 244.46364 Signed-off-by: Esteban Rodriguez Betancourt --- I can't believe that I didn't send the patch in the previous mail, sorry about that. Regards, Esteban lib/json.c | 76 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/lib/json.c b/lib/json.c index 995f3c2..080e881 100644 --- a/lib/json.c +++ b/lib/json.c @@ -1610,49 +1610,53 @@ json_serialize_array(const struct json_array *array, struct json_serializer *s) ds_put_char(ds, ']'); } +const char *chars_escaping[256] = { + "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007", + "\\b", "\\t", "\\n", "\\u000b", "\\f", "\\r", "\\u000e", "\\u000f", + "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017", + "\\u0018", "\\u0019", "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f", + " ", "!", "\\\"", "#", "$", "%", "&", "'", + "(", ")", "*", "+", ",", "-", ".", "/", + "0", "1", "2", "3", "4", "5", "6", "7", + "8", "9", ":", ";", "<", "=", ">", "?", + "@", "A", "B", "C", "D", "E", "F", "G", + "H", "I", "J", "K", "L", "M", "N", "O", + "P", "Q", "R", "S", "T", "U", "V", "W", + "X", "Y", "Z", "[", "\\\\", "]", "^", "_", + "`", "a", "b", "c", "d", "e", "f", "g", + "h", "i", "j", "k", "l", "m", "n", "o", + "p", "q", "r", "s", "t", "u", "v", "w", + "x", "y", "z", "{", "|", "}", "~", "\x7f", + "\x80", "\x81", "\x82", "\x83", "\x84", "\x85", "\x86", "\x87", + "\x88", "\x89", "\x8a", "\x8b", "\x8c", "\x8d", "\x8e", "\x8f", + "\x90", "\x91", "\x92", "\x93", "\x94", "\x95", "\x96", "\x97", + "\x98", "\x99", "\x9a", "\x9b", "\x9c", "\x9d", "\x9e", "\x9f", + "\xa0", "\xa1", "\xa2", "\xa3", "\xa4", "\xa5", "\xa6", "\xa7", + "\xa8", "\xa9", "\xaa", "\xab", "\xac", "\xad", "\xae", "\xaf", + "\xb0", "\xb1", "\xb2", "\xb3", "\xb4", "\xb5", "\xb6", "\xb7", + "\xb8", "\xb9", "\xba", "\xbb", "\xbc", "\xbd", "\xbe", "\xbf", + "\xc0", "\xc1", "\xc2", "\xc3", "\xc4", "\xc5", "\xc6", "\xc7", + "\xc8", "\xc9", "\xca", "\xcb", "\xcc", "\xcd", "\xce", "\xcf", + "\xd0", "\xd1", "\xd2", "\xd3", "\xd4", "\xd5", "\xd6", "\xd7", + "\xd8", "\xd9", "\xda", "\xdb", "\xdc", "\xdd", "\xde", "\xdf", + "\xe0", "\xe1", "\xe2", "\xe3", "\xe4", "\xe5", "\xe6", "\xe7", + "\xe8", "\xe9", "\xea", "\xeb", "\xec", "\xed", "\xee", "\xef", + "\xf0", "\xf1", "\xf2", "\xf3", "\xf4", "\xf5", "\xf6", "\xf7", + "\xf8", "\xf9", "\xfa", "\xfb", "\xfc", "\xfd", "\xfe", "\xff" +}; + static void json_serialize_string(const char *string, struct ds *ds) { uint8_t c; + uint8_t c2; + const char *escape; ds_put_char(ds, '"'); while ((c = *string++) != '\0') { - switch (c) { - case '"': - ds_put_cstr(ds, "\\\""); - break; - - case '\\': - ds_put_cstr(ds, "\\\\"); - break; - - case '\b': - ds_put_cstr(ds, "\\b"); - break; - - case '\f': - ds_put_cstr(ds, "\\f"); - break; - - case '\n': - ds_put_cstr(ds, "\\n"); - break; - - case '\r': - ds_put_cstr(ds, "\\r"); - break; - - case '\t': - ds_put_cstr(ds, "\\t"); - break; - - default: - if (c >= 32) { - ds_put_char(ds, c); - } else { - ds_put_format(ds, "\\u%04x", c); - } - break; + escape = chars_escaping[c]; + while ((c2 = *escape++) != '\0') { + ds_put_char(ds, c2); } } ds_put_char(ds, '"');