Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Improve speed of byLine() on generic I/O

  • Loading branch information...
commit 94b21d38d16e075d7c44b53015eb1113854424d0 1 parent 8fef373
Andrei Alexandrescu authored

Showing 1 changed file with 28 additions and 4 deletions. Show diff stats Hide diff stats

  1. 32  std/stdio.d
32  std/stdio.d
@@ -936,8 +936,8 @@ Range that reads one line at a time. */
936 936
         /// Range primitive implementations.
937 937
         @property bool empty() const
938 938
         {
939  
-            if (!file.isOpen) return true;
940 939
             if (line !is null) return false;
  940
+            if (!file.isOpen) return true;
941 941
 
942 942
             // First read ever, must make sure stream is not empty. We
943 943
             // do so by reading a character and putting it back. Doing
@@ -966,11 +966,13 @@ Range that reads one line at a time. */
966 966
         /// Ditto
967 967
         void popFront()
968 968
         {
969  
-            enforce(file.isOpen);
  969
+            assert(file.isOpen);
  970
+            assumeSafeAppend(line);
970 971
             file.readln(line, terminator);
971 972
             if (line.empty)
972 973
             {
973 974
                 file.detach();
  975
+                line = null;
974 976
             }
975 977
             else if (keepTerminator == KeepTerminator.no
976 978
                     && std.algorithm.endsWith(line, terminator))
@@ -2554,13 +2556,35 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator = '\n')
2554 2556
     }
2555 2557
 
2556 2558
     // Narrow stream
2557  
-    buf.length = 0;
  2559
+    // First, fill the existing buffer
  2560
+    for (size_t bufPos = 0; bufPos < buf.length; )
  2561
+    {
  2562
+        immutable c = FGETC(fp);
  2563
+        if (c == -1)
  2564
+        {
  2565
+            buf.length = bufPos;
  2566
+            goto endGame;
  2567
+        }
  2568
+        buf.ptr[bufPos++] = cast(char) c;
  2569
+        if (c == terminator)
  2570
+        {
  2571
+            // No need to test for errors in file
  2572
+            buf.length = bufPos;
  2573
+            return bufPos;
  2574
+        }
  2575
+    }
  2576
+    // Then, append to it
2558 2577
     for (int c; (c = FGETC(fp)) != -1; )
2559 2578
     {
2560 2579
         buf ~= cast(char)c;
2561 2580
         if (c == terminator)
2562  
-            break;
  2581
+        {
  2582
+            // No need to test for errors in file
  2583
+            return buf.length;
  2584
+        }
2563 2585
     }
  2586
+
  2587
+  endGame:
2564 2588
     if (ferror(fps))
2565 2589
         StdioException();
2566 2590
     return buf.length;

0 notes on commit 94b21d3

Please sign in to comment.
Something went wrong with that request. Please try again.