Merge pull request #595 from triska/faster_format
ENHANCED: faster format/3 when writing to binary streams
This commit is contained in:
@@ -375,20 +375,9 @@ format(Fs, Args) :-
|
|||||||
format(Stream, Fs, Args) :-
|
format(Stream, Fs, Args) :-
|
||||||
phrase(format_(Fs, Args), Cs),
|
phrase(format_(Fs, Args), Cs),
|
||||||
( stream_property(Stream, type(binary)) ->
|
( stream_property(Stream, type(binary)) ->
|
||||||
% maplist(char_code, Cs, Bytes) is currently a lot slower
|
|
||||||
% than first converting Cs to an atom, and then to codes.
|
|
||||||
% In the future, we can ideally avoid creating an atom here,
|
|
||||||
% since an atom leaves traces in the system.
|
|
||||||
atom_chars(A, Cs),
|
|
||||||
atom_codes(A, Bytes),
|
|
||||||
( member(NonByte, Bytes), NonByte > 255 ->
|
|
||||||
char_code(Char, NonByte),
|
|
||||||
throw(error(representation_error(Char), format/3))
|
|
||||||
; true
|
|
||||||
),
|
|
||||||
% For binary streams, we use a specialised internal predicate
|
% For binary streams, we use a specialised internal predicate
|
||||||
% that uses only a single "write" operation for efficiency.
|
% that uses only a single "write" operation for efficiency.
|
||||||
'$put_bytes'(Stream, Bytes)
|
'$put_bytes'(Stream, Cs)
|
||||||
; maplist(put_char(Stream), Cs)
|
; maplist(put_char(Stream), Cs)
|
||||||
).
|
).
|
||||||
|
|
||||||
@@ -471,7 +460,7 @@ portray_clause(Term) :-
|
|||||||
|
|
||||||
portray_clause(Stream, Term) :-
|
portray_clause(Stream, Term) :-
|
||||||
phrase(portray_clause_(Term), Ls),
|
phrase(portray_clause_(Term), Ls),
|
||||||
maplist(put_char(Stream), Ls).
|
format(Stream, "~s", [Ls]).
|
||||||
|
|
||||||
portray_clause_(Term) -->
|
portray_clause_(Term) -->
|
||||||
{ term_variables(Term, Vs),
|
{ term_variables(Term, Vs),
|
||||||
|
|||||||
@@ -2022,8 +2022,24 @@ impl MachineState {
|
|||||||
let mut stream =
|
let mut stream =
|
||||||
self.get_stream_or_alias(self[temp_v!(1)], indices, "$put_bytes", 2)?;
|
self.get_stream_or_alias(self[temp_v!(1)], indices, "$put_bytes", 2)?;
|
||||||
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("$put_bytes"), 2);
|
let mut iter = self.heap_pstr_iter(self[temp_v!(2)]);
|
||||||
let bytes = self.integers_to_bytevec(temp_v!(2), stub);
|
let mut bytes = Vec::new();
|
||||||
|
for c in iter.to_string().chars() {
|
||||||
|
if c as u32 > 255 {
|
||||||
|
|
||||||
|
let stub = MachineError::functor_stub(clause_name!("$put_bytes"), 2);
|
||||||
|
|
||||||
|
let err = MachineError::type_error(
|
||||||
|
self.heap.h(),
|
||||||
|
ValidType::Byte,
|
||||||
|
Addr::Char(c),
|
||||||
|
);
|
||||||
|
|
||||||
|
return Err(self.error_form(err, stub));
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes.push(c as u8);
|
||||||
|
}
|
||||||
|
|
||||||
match stream.write(&bytes) {
|
match stream.write(&bytes) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user