Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: src/conversions.cc

Issue 597007: Faster implementation of integer-to-ascii conversion. I think.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/conversions.h ('k') | src/heap.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 builder.AddFormatted("%d", exponent); 418 builder.AddFormatted("%d", exponent);
419 } 419 }
420 420
421 freedtoa(decimal_rep); 421 freedtoa(decimal_rep);
422 } 422 }
423 } 423 }
424 return builder.Finalize(); 424 return builder.Finalize();
425 } 425 }
426 426
427 427
428 // Tables and constants for fast integer to ASCII conversion.
429 // Contains the first 1000 integers in ASCII form. Each integer starts with
430 // a minus (-), which is skipped for positive numbers.
431 static const int kIToATableStride = 4;
432 static const char* kIToATable =
433 "-0..-1---2..-3..-4..-5..-6..-7..-8..-9.."
434 "-10.-11.-12.-13.-14.-15.-16.-17.-18.-19."
435 "-20.-21.-22.-23.-24.-25.-26.-27.-28.-29."
436 "-30.-31.-32.-33.-34.-35.-36.-37.-38.-39."
437 "-40.-41.-42.-43.-44.-45.-46.-47.-48.-49."
438 "-50.-51.-52.-53.-54.-55.-56.-57.-58.-59."
439 "-60.-61.-62.-63.-64.-65.-66.-67.-68.-69."
440 "-70.-71.-72.-73.-74.-75.-76.-77.-78.-79."
441 "-80.-81.-82.-83.-84.-85.-86.-87.-88.-89."
442 "-90.-91.-92.-93.-94.-95.-96.-97.-98.-99."
443 "-100-101-102-103-104-105-106-107-108-109"
444 "-110-111-112-113-114-115-116-117-118-119"
445 "-120-121-122-123-124-125-126-127-128-129"
446 "-130-131-132-133-134-135-136-137-138-139"
447 "-140-141-142-143-144-145-146-147-148-149"
448 "-150-151-152-153-154-155-156-157-158-159"
449 "-160-161-162-163-164-165-166-167-168-169"
450 "-170-171-172-173-174-175-176-177-178-179"
451 "-180-181-182-183-184-185-186-187-188-189"
452 "-190-191-192-193-194-195-196-197-198-199"
453 "-200-201-202-203-204-205-206-207-208-209"
454 "-210-211-212-213-214-215-216-217-218-219"
455 "-220-221-222-223-224-225-226-227-228-229"
456 "-230-231-232-233-234-235-236-237-238-239"
457 "-240-241-242-243-244-245-246-247-248-249"
458 "-250-251-252-253-254-255-256-257-258-259"
459 "-260-261-262-263-264-265-266-267-268-269"
460 "-270-271-272-273-274-275-276-277-278-279"
461 "-280-281-282-283-284-285-286-287-288-289"
462 "-290-291-292-293-294-295-296-297-298-299"
463 "-300-301-302-303-304-305-306-307-308-309"
464 "-310-311-312-313-314-315-316-317-318-319"
465 "-320-321-322-323-324-325-326-327-328-329"
466 "-330-331-332-333-334-335-336-337-338-339"
467 "-340-341-342-343-344-345-346-347-348-349"
468 "-350-351-352-353-354-355-356-357-358-359"
469 "-360-361-362-363-364-365-366-367-368-369"
470 "-370-371-372-373-374-375-376-377-378-379"
471 "-380-381-382-383-384-385-386-387-388-389"
472 "-390-391-392-393-394-395-396-397-398-399"
473 "-400-401-402-403-404-405-406-407-408-409"
474 "-410-411-412-413-414-415-416-417-418-419"
475 "-420-421-422-423-424-425-426-427-428-429"
476 "-430-431-432-433-434-435-436-437-438-439"
477 "-440-441-442-443-444-445-446-447-448-449"
478 "-450-451-452-453-454-455-456-457-458-459"
479 "-460-461-462-463-464-465-466-467-468-469"
480 "-470-471-472-473-474-475-476-477-478-479"
481 "-480-481-482-483-484-485-486-487-488-489"
482 "-490-491-492-493-494-495-496-497-498-499"
483 "-500-501-502-503-504-505-506-507-508-509"
484 "-510-511-512-513-514-515-516-517-518-519"
485 "-520-521-522-523-524-525-526-527-528-529"
486 "-530-531-532-533-534-535-536-537-538-539"
487 "-540-541-542-543-544-545-546-547-548-549"
488 "-550-551-552-553-554-555-556-557-558-559"
489 "-560-561-562-563-564-565-566-567-568-569"
490 "-570-571-572-573-574-575-576-577-578-579"
491 "-580-581-582-583-584-585-586-587-588-589"
492 "-590-591-592-593-594-595-596-597-598-599"
493 "-600-601-602-603-604-605-606-607-608-609"
494 "-610-611-612-613-614-615-616-617-618-619"
495 "-620-621-622-623-624-625-626-627-628-629"
496 "-630-631-632-633-634-635-636-637-638-639"
497 "-640-641-642-643-644-645-646-647-648-649"
498 "-650-651-652-653-654-655-656-657-658-659"
499 "-660-661-662-663-664-665-666-667-668-669"
500 "-670-671-672-673-674-675-676-677-678-679"
501 "-680-681-682-683-684-685-686-687-688-689"
502 "-690-691-692-693-694-695-696-697-698-699"
503 "-700-701-702-703-704-705-706-707-708-709"
504 "-710-711-712-713-714-715-716-717-718-719"
505 "-720-721-722-723-724-725-726-727-728-729"
506 "-730-731-732-733-734-735-736-737-738-739"
507 "-740-741-742-743-744-745-746-747-748-749"
508 "-750-751-752-753-754-755-756-757-758-759"
509 "-760-761-762-763-764-765-766-767-768-769"
510 "-770-771-772-773-774-775-776-777-778-779"
511 "-780-781-782-783-784-785-786-787-788-789"
512 "-790-791-792-793-794-795-796-797-798-799"
513 "-800-801-802-803-804-805-806-807-808-809"
514 "-810-811-812-813-814-815-816-817-818-819"
515 "-820-821-822-823-824-825-826-827-828-829"
516 "-830-831-832-833-834-835-836-837-838-839"
517 "-840-841-842-843-844-845-846-847-848-849"
518 "-850-851-852-853-854-855-856-857-858-859"
519 "-860-861-862-863-864-865-866-867-868-869"
520 "-870-871-872-873-874-875-876-877-878-879"
521 "-880-881-882-883-884-885-886-887-888-889"
522 "-890-891-892-893-894-895-896-897-898-899"
523 "-900-901-902-903-904-905-906-907-908-909"
524 "-910-911-912-913-914-915-916-917-918-919"
525 "-920-921-922-923-924-925-926-927-928-929"
526 "-930-931-932-933-934-935-936-937-938-939"
527 "-940-941-942-943-944-945-946-947-948-949"
528 "-950-951-952-953-954-955-956-957-958-959"
529 "-960-961-962-963-964-965-966-967-968-969"
530 "-970-971-972-973-974-975-976-977-978-979"
531 "-980-981-982-983-984-985-986-987-988-989"
532 "-990-991-992-993-994-995-996-997-998-999";
533
534
535 // Table that maps i to the ASCII representation of i. Only the
536 // even numbers are in the table since the odd ones can be
537 // branchlessly created from those.
538 static const int kLeadingZerosIToATableStride = 3;
539 static const char* kLeadingZerosIToATable =
540 "000002004006008010012014016018020022024026028030032034036038"
541 "040042044046048050052054056058060062064066068070072074076078"
542 "080082084086088090092094096098100102104106108110112114116118"
543 "120122124126128130132134136138140142144146148150152154156158"
544 "160162164166168170172174176178180182184186188190192194196198"
545 "200202204206208210212214216218220222224226228230232234236238"
546 "240242244246248250252254256258260262264266268270272274276278"
547 "280282284286288290292294296298300302304306308310312314316318"
548 "320322324326328330332334336338340342344346348350352354356358"
549 "360362364366368370372374376378380382384386388390392394396398"
550 "400402404406408410412414416418420422424426428430432434436438"
551 "440442444446448450452454456458460462464466468470472474476478"
552 "480482484486488490492494496498500502504506508510512514516518"
553 "520522524526528530532534536538540542544546548550552554556558"
554 "560562564566568570572574576578580582584586588590592594596598"
555 "600602604606608610612614616618620622624626628630632634636638"
556 "640642644646648650652654656658660662664666668670672674676678"
557 "680682684686688690692694696698700702704706708710712714716718"
558 "720722724726728730732734736738740742744746748750752754756758"
559 "760762764766768770772774776778780782784786788790792794796798"
560 "800802804806808810812814816818820822824826828830832834836838"
561 "840842844846848850852854856858860862864866868870872874876878"
562 "880882884886888890892894896898900902904906908910912914916918"
563 "920922924926928930932934936938940942944946948950952954956958"
564 "960962964966968970972974976978980982984986988990992994996998";
565
566 // Table that maps i/2 to the length of i in characters.
567 static char kIToALengthTable[500] = {
568 1, 1, 1, 1, 1,
569 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
570 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
571 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
572 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
573 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
574 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
575 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
576 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
577 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
578 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
579 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
580 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
581 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
582 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
583 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
584 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
585 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
586 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
587 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
588 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3};
589
590
591 static char i_to_a_answer_buffer[12];
592
593
594 // Calculate ASCII representation of a number 3 digits at a time.
595 static char* RecursiveIToA(char* dest, int i) {
596 int low_triplet;
597 int thousands = 0;
598 while (true) {
599 low_triplet = (i & 1023);
600 int new_high_triplet = i >> 10;
601 low_triplet += new_high_triplet * 24;
602 thousands += new_high_triplet;
603 if (low_triplet < 1000) break;
604 if (low_triplet < 2000) {
605 low_triplet -= 1000;
606 thousands++;
607 break;
608 }
609 i = low_triplet;
610 }
611 if (thousands < 10) {
612 *dest++ = kIToATable[thousands * kIToATableStride + 1];
613 } else if (thousands < 100) {
614 dest[0] = kIToATable[thousands * kIToATableStride + 1];
615 dest[1] = kIToATable[thousands * kIToATableStride + 2];
616 dest += 2;
617 } else if (thousands < 1000) {
618 dest[0] = kIToATable[thousands * kIToATableStride + 1];
619 dest[1] = kIToATable[thousands * kIToATableStride + 2];
620 dest[2] = kIToATable[thousands * kIToATableStride + 3];
621 dest += 3;
622 } else {
623 dest = RecursiveIToA(dest, thousands);
624 }
625 const char* ascii_triplet = kLeadingZerosIToATable +
626 (low_triplet >> 1) * kLeadingZerosIToATableStride;
627 dest[0] = ascii_triplet[0];
628 dest[1] = ascii_triplet[1];
629 dest[2] = (ascii_triplet[2] | (low_triplet & 1));
630 return dest + 3;
631 }
632
633
634 // Takes a 32 bit integer and returns a pointer to an ASCII representation of
635 // that integer. The caller need not free the returned representation. The
636 // ASCII representation is not necessarily null terminated, but the length is
637 // written back to the 'len' argument.
638 const char* IntToCString(int i, int* len) {
639 char* answer = i_to_a_answer_buffer;
640 if (i >= 0) {
641 if (i < 1000) {
642 // Handle 0-1000 by just returning a pointer to the table.
643 *len = kIToALengthTable[i >> 1];
644 return kIToATable + i * kIToATableStride + 1;
645 }
646 answer = RecursiveIToA(answer, i);
647 *len = answer - i_to_a_answer_buffer;
648 return i_to_a_answer_buffer;
649 } else {
650 // Negative numbers.
651 // Handle specially since there is no 32 bit positive representation of
652 // this number. The C compiler seems to get very confused about it so
653 // we cast to unsigned to avoid warnings.
654 if (static_cast<unsigned>(i) == 2147483648u) {
655 *len = 11;
656 return "-2147483648";
657 }
658 i = -i;
659 if (i < 1000) {
660 if (i < 1000) {
661 *len = kIToALengthTable[i >> 1] + 1;
662 return kIToATable + i * kIToATableStride;
663 }
664 }
665 *answer++ = '-';
666 answer = RecursiveIToA(answer, i);
667 *len = answer - i_to_a_answer_buffer;
668 return i_to_a_answer_buffer;
669 }
670 }
671
672
673
428 const char* IntToCString(int n, Vector<char> buffer) { 674 const char* IntToCString(int n, Vector<char> buffer) {
429 bool negative = false; 675 bool negative = false;
430 if (n < 0) { 676 if (n < 0) {
431 // We must not negate the most negative int. 677 // We must not negate the most negative int.
432 if (n == kMinInt) return DoubleToCString(n, buffer); 678 if (n == kMinInt) return DoubleToCString(n, buffer);
433 negative = true; 679 negative = true;
434 n = -n; 680 n = -n;
435 } 681 }
436 // Build the string backwards from the least significant digit. 682 // Build the string backwards from the least significant digit.
437 int i = buffer.length(); 683 int i = buffer.length();
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 // Allocate result and fill in the parts. 946 // Allocate result and fill in the parts.
701 StringBuilder builder(result_size + 1); 947 StringBuilder builder(result_size + 1);
702 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size); 948 builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size);
703 if (decimal_pos > 0) builder.AddCharacter('.'); 949 if (decimal_pos > 0) builder.AddCharacter('.');
704 builder.AddSubstring(decimal_buffer, decimal_pos); 950 builder.AddSubstring(decimal_buffer, decimal_pos);
705 return builder.Finalize(); 951 return builder.Finalize();
706 } 952 }
707 953
708 954
709 } } // namespace v8::internal 955 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/conversions.h ('k') | src/heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698